You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1714 lines
55 KiB
1714 lines
55 KiB
//
|
|
//
|
|
// C++ Implementation: tdefilereplacepart
|
|
//
|
|
// Description:
|
|
//
|
|
//
|
|
// Author: Andras Mantia <amantia@kde.org>, (C) 2003
|
|
// Maintainer: Emiliano Gulmini <emi_barbarossa@yahoo.it>, (C) 2004
|
|
//
|
|
// Copyright: GPL v2. See COPYING file that comes with this distribution
|
|
//
|
|
//
|
|
|
|
// QT
|
|
#include <tqdir.h>
|
|
#include <tqdatastream.h>
|
|
#include <tqregexp.h>
|
|
#include <tqimage.h>
|
|
#include <tqtextcodec.h>
|
|
|
|
// KDE
|
|
#include <dcopclient.h>
|
|
#include <dcopref.h>
|
|
#include <tdeaboutapplication.h>
|
|
#include <tdeapplication.h>
|
|
#include <tdeaction.h>
|
|
#include <kbugreport.h>
|
|
#include <tdeconfig.h>
|
|
#include <tdefiledialog.h>
|
|
#include <kinstance.h>
|
|
#include <tdeio/netaccess.h>
|
|
#include <tdelocale.h>
|
|
#include <tdemessagebox.h>
|
|
#include <tdeparts/genericfactory.h>
|
|
#include <kstandarddirs.h>
|
|
#include <kiconloader.h>
|
|
#include <tdeglobal.h>
|
|
#include <kiconeffect.h>
|
|
#include <tdelistview.h>
|
|
#include <kuser.h>
|
|
#include <kcombobox.h>
|
|
#include <kguiitem.h>
|
|
|
|
// local
|
|
#include "tdefilereplacelib.h"
|
|
#include "tdefilereplacepart.h"
|
|
#include "tdefilereplaceview.h"
|
|
#include "koptionsdlg.h"
|
|
#include "knewprojectdlg.h"
|
|
#include "report.h"
|
|
#include "commandengine.h"
|
|
#include "whatthis.h"
|
|
|
|
// Change this as well if increasing the max value allowed for the m_spbMaxDepth spinbox
|
|
static const int CIRCULAR_LINK_DETECTION_LEVEL = 256;
|
|
|
|
using namespace whatthisNameSpace;
|
|
|
|
//PUBLIC CONSTRUCTORS
|
|
// Factory code for KDE 3
|
|
typedef KParts::GenericFactory<TDEFileReplacePart> FileReplaceFactory;
|
|
|
|
K_EXPORT_COMPONENT_FACTORY( libtdefilereplacepart, FileReplaceFactory )
|
|
|
|
TDEFileReplacePart::TDEFileReplacePart(TQWidget* parentWidget, const char* , TQObject* parent, const char* name, const TQStringList & ) : KParts::ReadOnlyPart(parent,name)
|
|
{
|
|
setInstance(FileReplaceFactory::instance());
|
|
TDEGlobal::locale()->insertCatalogue("tdefilereplace");
|
|
m_parentWidget = parentWidget;
|
|
m_config = new TDEConfig("tdefilereplacerc");
|
|
m_aboutDlg = 0;
|
|
m_stop = false;
|
|
m_optionMask = TQDir::Files;
|
|
m_w = widget();
|
|
m_option = 0;
|
|
m_circ_ref_warning_shown = false;
|
|
|
|
loadOptionsFromRC();
|
|
initView();
|
|
initGUI();
|
|
|
|
whatsThis();
|
|
}
|
|
|
|
TDEFileReplacePart::~TDEFileReplacePart()
|
|
{
|
|
m_view = 0; //it's already deleted, so set it to NULL
|
|
|
|
saveOptionsToRC();
|
|
|
|
delete m_aboutDlg;
|
|
m_aboutDlg = 0;
|
|
delete m_config;
|
|
m_config = 0;
|
|
delete m_w;
|
|
m_w = 0;
|
|
delete m_option;
|
|
}
|
|
|
|
//PRIVATE SLOTS
|
|
void TDEFileReplacePart::slotSetNewParameters()
|
|
{
|
|
launchNewProjectDialog(KURL());
|
|
m_view->changeView(m_option->m_searchingOnlyMode);
|
|
emit setStatusBarText(i18n("Ready."));
|
|
}
|
|
|
|
void TDEFileReplacePart::slotSearchingOperation()
|
|
{
|
|
if(!checkBeforeOperation())
|
|
return;
|
|
|
|
TDEListView* rv = m_view->getResultsView();
|
|
|
|
rv->clear();
|
|
|
|
rv->setSorting(-1);
|
|
|
|
// show wait cursor
|
|
TQApplication::setOverrideCursor( TQt::waitCursor );
|
|
|
|
freezeActions();
|
|
|
|
setOptionMask();
|
|
|
|
TQString currentDirectory = m_option->m_directories[0],
|
|
currentFilter = m_option->m_filters[0];
|
|
|
|
//m_currentDir = currentDirectory;
|
|
|
|
m_view->showSemaphore("red");
|
|
|
|
uint filesNumber = 0;
|
|
|
|
if(m_option->m_recursive)
|
|
{
|
|
m_circ_ref_warning_shown = false;
|
|
recursiveFileSearch(currentDirectory, currentFilter, filesNumber, 0);
|
|
}
|
|
else
|
|
fileSearch(currentDirectory, currentFilter);
|
|
|
|
m_view->showSemaphore("yellow");
|
|
|
|
kapp->processEvents();
|
|
|
|
//disabling and enabling sorting... don't ask me why, but it works!
|
|
rv->setSorting(0);
|
|
rv->sort();
|
|
rv->setSorting(-1);
|
|
|
|
// restore false status for stop button
|
|
m_stop = false;
|
|
|
|
TQApplication::restoreOverrideCursor();
|
|
|
|
emit setStatusBarText(i18n("Search completed."));
|
|
|
|
m_option->m_searchingOnlyMode = true;
|
|
|
|
resetActions();
|
|
|
|
m_searchingOperation = true;
|
|
|
|
m_view->showSemaphore("green");
|
|
}
|
|
|
|
void TDEFileReplacePart::slotReplacingOperation()
|
|
{
|
|
if (KMessageBox::warningContinueCancel(m_w, i18n("<qt>You have selected <b>%1</b> as the encoding of the files.<br>Selecting the correct encoding is very important as if you have files that have some other encoding than the selected one, after a replace you may damage those files.<br><br>In case you do not know the encoding of your files, select <i>utf8</i> and <b>enable</b> the creation of backup files. This setting will autodetect <i>utf8</i> and <i>utf16</i> files, but the changed files will be converted to <i>utf8</i>.</qt>").arg(m_option->m_encoding), i18n("File Encoding Warning"), KStdGuiItem::cont(), "ShowEncodingWarning") == KMessageBox::Cancel)
|
|
return;
|
|
if(!checkBeforeOperation())
|
|
return;
|
|
|
|
TDEListView* rv = m_view->getResultsView();
|
|
|
|
if(m_option->m_simulation)
|
|
{
|
|
emit setStatusBarText(i18n("Replacing files (simulation)..."));
|
|
rv->setColumnText(4,i18n("Replaced strings (simulation)"));
|
|
}
|
|
else
|
|
{
|
|
emit setStatusBarText(i18n("Replacing files..."));
|
|
rv->setColumnText(4,i18n("Replaced strings"));
|
|
}
|
|
// show wait cursor
|
|
TQApplication::setOverrideCursor( TQt::waitCursor );
|
|
|
|
freezeActions();
|
|
|
|
setOptionMask();
|
|
|
|
rv->setSorting(-1);
|
|
|
|
m_view->showSemaphore("green");
|
|
|
|
TQString currentDirectory = m_option->m_directories[0];
|
|
|
|
m_view->showSemaphore("red");
|
|
|
|
if(m_option->m_recursive)
|
|
{
|
|
int filesNumber = 0;
|
|
m_circ_ref_warning_shown = false;
|
|
recursiveFileReplace(currentDirectory, filesNumber, 0);
|
|
}
|
|
else
|
|
{
|
|
fileReplace();
|
|
}
|
|
|
|
rv->setSorting(0);
|
|
rv->sort();
|
|
rv->setSorting(-1);
|
|
|
|
// restore false status for stop button
|
|
m_stop = false;
|
|
|
|
TQApplication::restoreOverrideCursor();
|
|
|
|
m_option->m_searchingOnlyMode = false;
|
|
|
|
resetActions();
|
|
|
|
m_searchingOperation = false;
|
|
|
|
m_view->showSemaphore("green");
|
|
}
|
|
|
|
void TDEFileReplacePart::slotSimulatingOperation()
|
|
{
|
|
m_option->m_simulation = true;
|
|
slotReplacingOperation();
|
|
m_option->m_simulation = false;
|
|
}
|
|
|
|
void TDEFileReplacePart::slotStop()
|
|
{
|
|
emit setStatusBarText(i18n("Stopping..."));
|
|
m_stop = true;
|
|
TQApplication::restoreOverrideCursor();
|
|
resetActions();
|
|
}
|
|
|
|
void TDEFileReplacePart::slotCreateReport()
|
|
{
|
|
// Check there are results
|
|
TDEListView* rv = m_view->getResultsView(),
|
|
* sv = m_view->getStringsView();
|
|
|
|
if(rv->firstChild() == 0)
|
|
{
|
|
KMessageBox::error(m_w, i18n("There are no results to save: the result list is empty."));
|
|
return ;
|
|
}
|
|
// Select the file where results will be saved
|
|
TQString documentName = KFileDialog::getSaveFileName(TQString(), "*.xml|XML " + i18n("Files") + " (*.xml)", m_w, i18n("Save Report"));
|
|
if (documentName.isEmpty())
|
|
return ;
|
|
|
|
// delete a spourious extension
|
|
documentName.truncate(documentName.length()-4);
|
|
|
|
TQFileInfo fileInfo(documentName);
|
|
if(fileInfo.exists())
|
|
{
|
|
KMessageBox::error(m_w, i18n("<qt>A folder or a file named <b>%1</b> already exists.</qt>").arg(documentName));
|
|
return ;
|
|
}
|
|
|
|
TQDir directoryName;
|
|
|
|
if(!directoryName.mkdir(documentName, true))
|
|
{
|
|
KMessageBox::error(m_w, i18n("<qt>Cannot create the <b>%1</b> folder.</qt>").arg(documentName));
|
|
return ;
|
|
}
|
|
|
|
directoryName.cd(documentName);
|
|
|
|
TQString documentPath = documentName+"/"+directoryName.dirName();
|
|
|
|
Report report(m_option, rv, sv);
|
|
report.createDocument(documentPath);
|
|
|
|
//resetActions();
|
|
}
|
|
|
|
void TDEFileReplacePart::slotStringsAdd()
|
|
{
|
|
m_view->slotStringsAdd();
|
|
resetActions();
|
|
}
|
|
|
|
void TDEFileReplacePart::slotQuickStringsAdd()
|
|
{
|
|
//this slot handles a pair of strings that come from project dialog,
|
|
//if the control character 'N' is found at the position 0 of the two strings,
|
|
//then we start the search now.
|
|
TQString qs = m_option->m_quickSearchString;
|
|
TQStringList map;
|
|
|
|
map.append(qs.left(1));
|
|
map.append(qs.right(qs.length()-1));
|
|
//in this case there is no string to search for, so return
|
|
if(map[1].isEmpty())
|
|
return;
|
|
|
|
//in this one instead, we must search for a string
|
|
qs = m_option->m_quickReplaceString;
|
|
map.append(qs.left(1));
|
|
map.append(qs.right(qs.length()-1));
|
|
|
|
m_view->updateOptions(m_option);
|
|
|
|
m_view->slotQuickStringsAdd(map[1],map[3]);
|
|
|
|
//if search-only mode == true and search-now mode == true then
|
|
//search string
|
|
if(map[0] == "N")
|
|
if(m_option->m_searchingOnlyMode)
|
|
slotSearchingOperation();
|
|
else
|
|
slotReplacingOperation();
|
|
}
|
|
|
|
void TDEFileReplacePart::slotStringsDeleteItem()
|
|
{
|
|
m_view->slotStringsDeleteItem();
|
|
resetActions();
|
|
}
|
|
|
|
void TDEFileReplacePart::slotStringsEmpty()
|
|
{
|
|
m_view->slotStringsEmpty();
|
|
resetActions();
|
|
}
|
|
|
|
void TDEFileReplacePart::slotStringsEdit()
|
|
{
|
|
m_view->slotStringsEdit();
|
|
resetActions();
|
|
}
|
|
|
|
void TDEFileReplacePart::slotStringsSave()
|
|
{
|
|
m_view->slotStringsSave();
|
|
}
|
|
|
|
void TDEFileReplacePart::slotStringsLoad()
|
|
{
|
|
// Selects the file to load from
|
|
TQString menu = "*.kfr|" + i18n("TDEFileReplace strings") + " (*.kfr)\n*|"+i18n("All Files") + " (*)";
|
|
TQString fileName = KFileDialog::getOpenFileName(TQString(), menu, m_w, i18n("Load Strings From File"));
|
|
|
|
if(!fileName.isEmpty())
|
|
loadRulesFile(fileName);
|
|
|
|
resetActions();
|
|
}
|
|
|
|
void TDEFileReplacePart::slotStringsInvertCur()
|
|
{
|
|
m_view->stringsInvert(false);
|
|
resetActions();
|
|
}
|
|
|
|
void TDEFileReplacePart::slotStringsInvertAll()
|
|
{
|
|
m_view->stringsInvert(true);
|
|
resetActions();
|
|
}
|
|
|
|
void TDEFileReplacePart::slotOpenRecentStringFile(const KURL& urlFile)
|
|
{
|
|
TQString fileName;
|
|
|
|
// Downloads file if need (if url is "http://...")
|
|
if (!(TDEIO::NetAccess::download(urlFile, fileName, 0)))
|
|
return;
|
|
|
|
// Checks it's not a directory
|
|
TQFileInfo fileInfo;
|
|
fileInfo.setFile(fileName);
|
|
if(fileInfo.isDir())
|
|
{
|
|
KMessageBox::error(m_w, i18n("Cannot open folders."));
|
|
return;
|
|
}
|
|
|
|
loadRulesFile(fileName);
|
|
resetActions();
|
|
}
|
|
|
|
void TDEFileReplacePart::slotOptionRecursive()
|
|
{
|
|
m_option->m_recursive = !m_option->m_recursive;
|
|
resetActions();
|
|
}
|
|
|
|
void TDEFileReplacePart::slotOptionBackup()
|
|
{
|
|
m_option->m_backup = !m_option->m_backup;
|
|
resetActions();
|
|
}
|
|
|
|
void TDEFileReplacePart::slotOptionCaseSensitive()
|
|
{
|
|
m_option->m_caseSensitive = !m_option->m_caseSensitive;
|
|
resetActions();
|
|
}
|
|
|
|
void TDEFileReplacePart::slotOptionVariables()
|
|
{
|
|
m_option->m_variables = !m_option->m_variables;
|
|
resetActions();
|
|
}
|
|
|
|
void TDEFileReplacePart::slotOptionRegularExpressions()
|
|
{
|
|
m_option->m_regularExpressions = !m_option->m_regularExpressions;
|
|
resetActions();
|
|
}
|
|
|
|
void TDEFileReplacePart::slotOptionPreferences()
|
|
{
|
|
KOptionsDlg dlg(m_option, m_w, 0);
|
|
|
|
if(!dlg.exec())
|
|
return;
|
|
|
|
//updating m_view
|
|
m_view->updateOptions(m_option);
|
|
|
|
resetActions();
|
|
}
|
|
|
|
void TDEFileReplacePart::showAboutApplication()
|
|
{
|
|
m_aboutDlg = new TDEAboutApplication(createAboutData(), (TQWidget *)0, (const char *)0, false);
|
|
if(m_aboutDlg == 0)
|
|
return;
|
|
|
|
if(!m_aboutDlg->isVisible())
|
|
m_aboutDlg->show();
|
|
else
|
|
m_aboutDlg->raise();
|
|
}
|
|
|
|
void TDEFileReplacePart::appHelpActivated()
|
|
{
|
|
kapp->invokeHelp(TQString(), "tdefilereplace");
|
|
}
|
|
|
|
void TDEFileReplacePart::reportBug()
|
|
{
|
|
KBugReport dlg(m_w, true, createAboutData());
|
|
dlg.exec();
|
|
}
|
|
|
|
void TDEFileReplacePart::resetActions()
|
|
{
|
|
TDEListView* rv = m_view->getResultsView(),
|
|
* sv = m_view->getStringsView();
|
|
|
|
bool hasItems = (sv->firstChild() != 0),
|
|
searchOnlyMode = m_option->m_searchingOnlyMode;
|
|
|
|
// File
|
|
actionCollection()->action("new_project")->setEnabled(true);
|
|
actionCollection()->action("search")->setEnabled(hasItems && searchOnlyMode);
|
|
actionCollection()->action("file_simulate")->setEnabled(hasItems && !searchOnlyMode);
|
|
actionCollection()->action("replace")->setEnabled(hasItems && !searchOnlyMode);
|
|
actionCollection()->action("save_results")->setEnabled(hasItems);
|
|
actionCollection()->action("stop")->setEnabled(false);
|
|
|
|
// Strings
|
|
actionCollection()->action("strings_add")->setEnabled(true);
|
|
actionCollection()->action("strings_del")->setEnabled(hasItems);
|
|
actionCollection()->action("strings_empty")->setEnabled(hasItems);
|
|
actionCollection()->action("strings_edit")->setEnabled(hasItems);
|
|
actionCollection()->action("strings_save")->setEnabled(hasItems);
|
|
actionCollection()->action("strings_load")->setEnabled(true);
|
|
actionCollection()->action("strings_invert")->setEnabled(hasItems && !searchOnlyMode);
|
|
actionCollection()->action("strings_invert_all")->setEnabled(hasItems && !searchOnlyMode);
|
|
|
|
// Options
|
|
actionCollection()->action("options_recursive")->setEnabled(true);
|
|
actionCollection()->action("options_backup")->setEnabled(!searchOnlyMode);
|
|
actionCollection()->action("options_case")->setEnabled(true);
|
|
actionCollection()->action("options_var")->setEnabled(!searchOnlyMode);
|
|
actionCollection()->action("options_regularexpressions")->setEnabled(true);
|
|
actionCollection()->action("configure_tdefilereplace")->setEnabled(true);
|
|
|
|
hasItems = (rv->firstChild() != 0);
|
|
|
|
// Results
|
|
actionCollection()->action("results_infos")->setEnabled(hasItems);
|
|
actionCollection()->action("results_openfile")->setEnabled(hasItems);
|
|
if (actionCollection()->action("results_editfile"))
|
|
actionCollection()->action("results_editfile")->setEnabled(hasItems);
|
|
actionCollection()->action("results_opendir")->setEnabled(hasItems);
|
|
actionCollection()->action("results_delete")->setEnabled(hasItems);
|
|
actionCollection()->action("results_treeexpand")->setEnabled(hasItems);
|
|
actionCollection()->action("results_treereduce")->setEnabled(hasItems);
|
|
|
|
// Updates menus and toolbar
|
|
((TDEToggleAction* ) actionCollection()->action("options_recursive"))->setChecked(m_option->m_recursive);
|
|
((TDEToggleAction* ) actionCollection()->action("options_backup"))->setChecked(m_option->m_backup && !searchOnlyMode);
|
|
((TDEToggleAction* ) actionCollection()->action("options_case"))->setChecked(m_option->m_caseSensitive);
|
|
((TDEToggleAction* ) actionCollection()->action("options_var"))->setChecked(m_option->m_variables && !searchOnlyMode);
|
|
((TDEToggleAction* ) actionCollection()->action("options_regularexpressions"))->setChecked(m_option->m_regularExpressions);
|
|
}
|
|
|
|
//PUBLIC METHODS
|
|
TDEAboutData* TDEFileReplacePart::createAboutData()
|
|
{
|
|
TDEAboutData * aboutData = new TDEAboutData("tdefilereplacepart",
|
|
I18N_NOOP("TDEFileReplacePart"),
|
|
KFR_VERSION,
|
|
I18N_NOOP( "Batch search and replace tool."),
|
|
TDEAboutData::License_GPL_V2,
|
|
"(C) 1999-2002 François Dupoux\n(C) 2003-2004 Andras Mantia\n(C) 2004 Emiliano Gulmini", I18N_NOOP("Part of the TDEUtils module."), "http://www.kdewebdev.org");
|
|
aboutData->addAuthor("François Dupoux",
|
|
I18N_NOOP("Original author of the TDEFileReplace tool"),
|
|
"dupoux@dupoux.com");
|
|
aboutData->addAuthor("Emiliano Gulmini",
|
|
I18N_NOOP("Current maintainer, code cleaner and rewriter"),
|
|
"emi_barbarossa@yahoo.it");
|
|
aboutData->addAuthor("Andras Mantia",
|
|
I18N_NOOP("Co-maintainer, KPart creator"),
|
|
"amantia@kde.org");
|
|
aboutData->addCredit("Heiko Goller",
|
|
I18N_NOOP("Original german translator"),
|
|
"heiko.goller@tuebingen.mpg.de");
|
|
return aboutData;
|
|
}
|
|
|
|
//PROTECTED METHODS
|
|
bool TDEFileReplacePart::openURL(const KURL &url)
|
|
{
|
|
if(!url.isEmpty() && (url.protocol() != "file"))
|
|
{
|
|
KMessageBox::sorry(m_w, i18n("Sorry, currently the TDEFileReplace part works only for local files."), i18n("Non Local File"));
|
|
emit canceled("");
|
|
return false;
|
|
}
|
|
if(!url.isEmpty())
|
|
return launchNewProjectDialog(url);
|
|
else
|
|
{
|
|
resetActions();
|
|
return true;
|
|
}
|
|
}
|
|
|
|
//PRIVATE METHODS
|
|
void TDEFileReplacePart::initGUI()
|
|
{
|
|
setXMLFile("tdefilereplacepartui.rc");
|
|
|
|
actionCollection()->setHighlightingEnabled(true);
|
|
|
|
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;
|
|
}
|
|
}
|
|
// File
|
|
(void)new TDEAction(i18n("Customize Search/Replace Session..."), "projectopen", TDEShortcut(CTRL + Key_F), TQT_TQOBJECT(this), TQT_SLOT(slotSetNewParameters()), actionCollection(), "new_project");
|
|
(void)new TDEAction(i18n("&Search"), "filesearch", 0, TQT_TQOBJECT(this), TQT_SLOT(slotSearchingOperation()), actionCollection(), "search");
|
|
(void)new TDEAction(i18n("S&imulate"), "filesimulate", 0, TQT_TQOBJECT(this), TQT_SLOT(slotSimulatingOperation()), actionCollection(), "file_simulate");
|
|
(void)new TDEAction(i18n("&Replace"), "filereplace", 0, TQT_TQOBJECT(this), TQT_SLOT(slotReplacingOperation()), actionCollection(), "replace");
|
|
(void)new TDEAction(i18n("Sto&p"), "process-stop", 0, TQT_TQOBJECT(this), TQT_SLOT(slotStop()), actionCollection(), "stop");
|
|
(void)new TDEAction(i18n("Cre&ate Report File..."), "document-save-as", 0, TQT_TQOBJECT(this), TQT_SLOT(slotCreateReport()), actionCollection(), "save_results");
|
|
|
|
// Strings
|
|
(void)new TDEAction(i18n("&Add String..."), "editadd", 0, TQT_TQOBJECT(this), TQT_SLOT(slotStringsAdd()), actionCollection(), "strings_add");
|
|
|
|
(void)new TDEAction(i18n("&Delete String"), "editremove", 0, TQT_TQOBJECT(this), TQT_SLOT(slotStringsDeleteItem()), actionCollection(), "strings_del");
|
|
(void)new TDEAction(i18n("&Empty Strings List"), "edit-delete", 0, TQT_TQOBJECT(this), TQT_SLOT(slotStringsEmpty()), actionCollection(), "strings_empty");
|
|
(void)new TDEAction(i18n("Edit Selected String..."), "edit", 0, TQT_TQOBJECT(this), TQT_SLOT(slotStringsEdit()), actionCollection(), "strings_edit");
|
|
(void)new TDEAction(i18n("&Save Strings List to File..."), "document-save-as", 0, TQT_TQOBJECT(this), TQT_SLOT(slotStringsSave()), actionCollection(), "strings_save");
|
|
(void)new TDEAction(i18n("&Load Strings List From File..."), "unsortedList", 0, TQT_TQOBJECT(this), TQT_SLOT(slotStringsLoad()), actionCollection(), "strings_load");
|
|
(void)new TDERecentFilesAction(i18n("&Load Recent Strings Files"), "document-open", 0, TQT_TQOBJECT(this), TQT_SLOT(slotOpenRecentStringFile(const KURL&)), actionCollection(),"strings_load_recent");
|
|
(void)new TDEAction(i18n("&Invert Current String (search <--> replace)"), "invert", 0, TQT_TQOBJECT(this), TQT_SLOT(slotStringsInvertCur()), actionCollection(), "strings_invert");
|
|
(void)new TDEAction(i18n("&Invert All Strings (search <--> replace)"), "invert", 0, TQT_TQOBJECT(this), TQT_SLOT(slotStringsInvertAll()), actionCollection(), "strings_invert_all");
|
|
|
|
// Options
|
|
(void)new TDEToggleAction(i18n("&Include Sub-Folders"), "recursive_option", 0, TQT_TQOBJECT(this), TQT_SLOT(slotOptionRecursive()), actionCollection(), "options_recursive");
|
|
(void)new TDEToggleAction(i18n("Create &Backup Files"), "backup_option", 0, TQT_TQOBJECT(this), TQT_SLOT(slotOptionBackup()), actionCollection(), "options_backup");
|
|
(void)new TDEToggleAction(i18n("Case &Sensitive"), "casesensitive_option", 0, TQT_TQOBJECT(this), TQT_SLOT(slotOptionCaseSensitive()), actionCollection(), "options_case");
|
|
(void)new TDEToggleAction(i18n("Enable Commands &in Replace String: [$command:option$]"), "command_option", 0, TQT_TQOBJECT(this), TQT_SLOT(slotOptionVariables()), actionCollection(), "options_var");
|
|
(void)new TDEToggleAction(i18n("Enable &Regular Expressions"), "regularexpression_option", 0, TQT_TQOBJECT(this), TQT_SLOT(slotOptionRegularExpressions()), actionCollection(), "options_regularexpressions");
|
|
(void)new TDEAction(i18n("Configure &TDEFileReplace..."), "configure", 0, TQT_TQOBJECT(this), TQT_SLOT(slotOptionPreferences()), actionCollection(), "configure_tdefilereplace");
|
|
|
|
// Results
|
|
(void)new TDEAction(i18n("&Properties"), "informations", 0, TQT_TQOBJECT(m_view), TQT_SLOT(slotResultProperties()), actionCollection(), "results_infos");
|
|
(void)new TDEAction(i18n("&Open"), "document-new", 0, TQT_TQOBJECT(m_view), TQT_SLOT(slotResultOpen()), actionCollection(), "results_openfile");
|
|
|
|
if(quantaFound)
|
|
{
|
|
(void)new TDEAction(i18n("&Edit in Quanta"), "quanta", 0, TQT_TQOBJECT(m_view), TQT_SLOT(slotResultEdit()), actionCollection(), "results_editfile");
|
|
}
|
|
(void)new TDEAction(i18n("Open Parent &Folder"), "document-open", 0, TQT_TQOBJECT(m_view), TQT_SLOT(slotResultDirOpen()), actionCollection(), "results_opendir");
|
|
(void)new TDEAction(i18n("&Delete"), "edit-delete", 0, TQT_TQOBJECT(m_view), TQT_SLOT(slotResultDelete()), actionCollection(), "results_delete");
|
|
(void)new TDEAction(i18n("E&xpand Tree"), 0, TQT_TQOBJECT(m_view), TQT_SLOT(slotResultTreeExpand()), actionCollection(), "results_treeexpand");
|
|
(void)new TDEAction(i18n("&Reduce Tree"), 0, TQT_TQOBJECT(m_view), TQT_SLOT(slotResultTreeReduce()), actionCollection(), "results_treereduce");
|
|
(void)new TDEAction(i18n("&About TDEFileReplace"), "tdefilereplace", 0, TQT_TQOBJECT(this), TQT_SLOT(showAboutApplication()), actionCollection(), "help_about_tdefilereplace");
|
|
(void)new TDEAction(i18n("TDEFileReplace &Handbook"), "help", 0, TQT_TQOBJECT(this), TQT_SLOT(appHelpActivated()), actionCollection(), "help_tdefilereplace");
|
|
(void)new TDEAction(i18n("&Report Bug"), 0, 0, TQT_TQOBJECT(this), TQT_SLOT(reportBug()), actionCollection(), "report_bug");
|
|
|
|
}
|
|
|
|
void TDEFileReplacePart::initView()
|
|
{
|
|
m_view = new TDEFileReplaceView(m_option, m_parentWidget, "view");
|
|
|
|
setWidget(m_view);
|
|
|
|
m_view->setAcceptDrops(false);
|
|
|
|
m_view->showSemaphore("green");
|
|
}
|
|
|
|
void TDEFileReplacePart::freezeActions()
|
|
{
|
|
//Disables actions during search/replace operation
|
|
actionCollection()->action("new_project")->setEnabled(false);
|
|
actionCollection()->action("stop")->setEnabled(true);
|
|
|
|
actionCollection()->action("file_simulate")->setEnabled(false);
|
|
actionCollection()->action("replace")->setEnabled(false);
|
|
actionCollection()->action("search")->setEnabled(false);
|
|
actionCollection()->action("strings_add")->setEnabled(false);
|
|
actionCollection()->action("strings_del")->setEnabled(false);
|
|
actionCollection()->action("strings_empty")->setEnabled(false);
|
|
actionCollection()->action("strings_edit")->setEnabled(false);
|
|
actionCollection()->action("strings_save")->setEnabled(false);
|
|
actionCollection()->action("strings_load")->setEnabled(false);
|
|
actionCollection()->action("strings_invert")->setEnabled(false);
|
|
actionCollection()->action("strings_invert_all")->setEnabled(false);
|
|
actionCollection()->action("options_recursive")->setEnabled(false);
|
|
actionCollection()->action("options_backup")->setEnabled(false);
|
|
actionCollection()->action("options_case")->setEnabled(false);
|
|
actionCollection()->action("options_var")->setEnabled(false);
|
|
actionCollection()->action("options_regularexpressions")->setEnabled(false);
|
|
actionCollection()->action("configure_tdefilereplace")->setEnabled(false);
|
|
actionCollection()->action("results_infos")->setEnabled(false);
|
|
actionCollection()->action("results_openfile")->setEnabled(false);
|
|
if (actionCollection()->action("results_editfile"))
|
|
actionCollection()->action("results_editfile")->setEnabled(false);
|
|
actionCollection()->action("results_opendir")->setEnabled(false);
|
|
actionCollection()->action("results_delete")->setEnabled(false);
|
|
actionCollection()->action("results_treeexpand")->setEnabled(false);
|
|
actionCollection()->action("results_treereduce")->setEnabled(false);
|
|
((TDEToggleAction* ) actionCollection()->action("options_recursive"))->setChecked(false);
|
|
((TDEToggleAction* ) actionCollection()->action("options_backup"))->setChecked(false);
|
|
((TDEToggleAction* ) actionCollection()->action("options_case"))->setChecked(false);
|
|
((TDEToggleAction* ) actionCollection()->action("options_var"))->setChecked(false);
|
|
((TDEToggleAction* ) actionCollection()->action("options_regularexpressions"))->setChecked(false);
|
|
}
|
|
|
|
void TDEFileReplacePart::loadOptionsFromRC()
|
|
{
|
|
m_option = new RCOptions();
|
|
|
|
loadOptions();
|
|
loadFileSizeOptions();
|
|
loadDateAccessOptions();
|
|
loadOwnerOptions();
|
|
loadLocationsList();
|
|
loadFiltersList();
|
|
loadBackupExtensionOptions();
|
|
}
|
|
|
|
void TDEFileReplacePart::loadOptions()
|
|
{
|
|
m_config->setGroup("General Options");
|
|
|
|
m_option->m_recentStringFileList = m_config->readListEntry(rcRecentFiles);
|
|
|
|
m_option->m_searchingOnlyMode = m_config->readBoolEntry(rcSearchMode,SearchModeOption);
|
|
|
|
m_config->setGroup("Options");
|
|
|
|
m_option->m_encoding = m_config->readEntry(rcEncoding, EncodingOption);
|
|
m_option->m_recursive = m_config->readBoolEntry(rcRecursive, RecursiveOption);
|
|
|
|
m_option->m_caseSensitive = m_config->readBoolEntry(rcCaseSensitive, CaseSensitiveOption);
|
|
m_option->m_variables = m_config->readBoolEntry(rcVariables, VariablesOption);
|
|
m_option->m_regularExpressions = m_config->readBoolEntry(rcRegularExpressions, RegularExpressionsOption);
|
|
m_option->m_followSymLinks = m_config->readBoolEntry(rcFollowSymLinks, FollowSymbolicLinksOption);
|
|
|
|
m_option->m_haltOnFirstOccur = m_config->readBoolEntry(rcHaltOnFirstOccur, StopWhenFirstOccurenceOption);
|
|
|
|
m_option->m_ignoreHidden = m_config->readBoolEntry(rcIgnoreHidden, IgnoreHiddenOption);
|
|
m_option->m_ignoreFiles = m_config->readBoolEntry(rcIgnoreFiles, IgnoreFilesOption);
|
|
|
|
m_config->setGroup("Notification Messages");
|
|
|
|
m_option->m_notifyOnErrors = m_config->readBoolEntry(rcNotifyOnErrors, true);
|
|
|
|
m_option->m_askConfirmReplace = m_config->readBoolEntry(rcAskConfirmReplace, AskConfirmReplaceOption);
|
|
|
|
TQString dontAskAgain = m_config->readEntry(rcDontAskAgain, "no");
|
|
|
|
if(dontAskAgain == "yes")
|
|
m_option->m_askConfirmReplace = false;
|
|
}
|
|
|
|
void TDEFileReplacePart::loadFileSizeOptions()
|
|
{
|
|
m_config->setGroup("Size options");
|
|
|
|
m_option->m_minSize = m_config->readNumEntry(rcMinFileSize, FileSizeOption);
|
|
m_option->m_maxSize = m_config->readNumEntry(rcMaxFileSize, FileSizeOption);
|
|
}
|
|
|
|
void TDEFileReplacePart::loadDateAccessOptions()
|
|
{
|
|
m_config->setGroup("Access options");
|
|
|
|
m_option->m_dateAccess = m_config->readEntry(rcValidAccessDate, ValidAccessDateOption);
|
|
m_option->m_minDate = m_config->readEntry(rcMinDate, AccessDateOption);
|
|
m_option->m_maxDate = m_config->readEntry(rcMaxDate, AccessDateOption);
|
|
}
|
|
|
|
void TDEFileReplacePart::loadOwnerOptions()
|
|
{
|
|
m_config->setGroup("Owner options");
|
|
|
|
TQStringList ownerList = TQStringList::split(',',m_config->readEntry(rcOwnerUser, OwnerOption),true);
|
|
if(ownerList[0] == "true")
|
|
m_option->m_ownerUserIsChecked = true;
|
|
else
|
|
m_option->m_ownerUserIsChecked = false;
|
|
|
|
m_option->m_ownerUserType = ownerList[1];
|
|
m_option->m_ownerUserBool = ownerList[2];
|
|
m_option->m_ownerUserValue = ownerList[3];
|
|
|
|
ownerList = TQStringList::split(',',m_config->readEntry(rcOwnerGroup, OwnerOption),true);
|
|
|
|
if(ownerList[0] == "true")
|
|
m_option->m_ownerGroupIsChecked = true;
|
|
else
|
|
m_option->m_ownerGroupIsChecked = false;
|
|
|
|
m_option->m_ownerGroupType = ownerList[1];
|
|
m_option->m_ownerGroupBool = ownerList[2];
|
|
m_option->m_ownerGroupValue = ownerList[3];
|
|
}
|
|
|
|
void TDEFileReplacePart::loadLocationsList()
|
|
{
|
|
m_config->setGroup("Directories");
|
|
TQStringList locationsEntryList;
|
|
#if KDE_IS_VERSION(3,1,3)
|
|
locationsEntryList = m_config->readPathListEntry(rcDirectoriesList);
|
|
#else
|
|
locationsEntryList = m_config->readListEntry(rcDirectoriesList);
|
|
#endif
|
|
|
|
if(locationsEntryList.isEmpty())
|
|
locationsEntryList.append(TQDir::current().path());
|
|
|
|
m_option->m_directories = locationsEntryList;
|
|
}
|
|
|
|
void TDEFileReplacePart::loadFiltersList()
|
|
{
|
|
TQStringList filtersEntryList;
|
|
|
|
m_config->setGroup("Filters");
|
|
#if KDE_IS_VERSION(3,1,3)
|
|
filtersEntryList = m_config->readPathListEntry(rcFiltersList);
|
|
#else
|
|
filtersEntryList = m_config->readListEntry(rcFiltersList);
|
|
#endif
|
|
|
|
if(filtersEntryList.isEmpty())
|
|
filtersEntryList.append("*.htm;*.html;*.xml;*.xhtml;*.css;*.js;*.php");
|
|
|
|
m_option->m_filters = filtersEntryList;
|
|
}
|
|
|
|
void TDEFileReplacePart::loadBackupExtensionOptions()
|
|
{
|
|
m_config->setGroup("Options");
|
|
TQStringList bkList = TQStringList::split(',',
|
|
m_config->readEntry(rcBackupExtension, BackupExtensionOption),
|
|
true);
|
|
if(bkList[0] == "true")
|
|
m_option->m_backup = true;
|
|
else
|
|
m_option->m_backup = false;
|
|
|
|
m_option->m_backupExtension = bkList[1];
|
|
}
|
|
|
|
void TDEFileReplacePart::saveOptionsToRC()
|
|
{
|
|
saveOptions();
|
|
saveFileSizeOptions();
|
|
saveDateAccessOptions();
|
|
saveOwnerOptions();
|
|
saveLocationsList();
|
|
saveFiltersList();
|
|
saveBackupExtensionOptions();
|
|
}
|
|
|
|
void TDEFileReplacePart::saveOptions()
|
|
{
|
|
m_config->setGroup("General Options");
|
|
|
|
m_config->writeEntry(rcRecentFiles, m_option->m_recentStringFileList);
|
|
m_config->writeEntry(rcSearchMode,m_option->m_searchingOnlyMode);
|
|
|
|
m_config->setGroup("Options");
|
|
|
|
m_config->writeEntry(rcEncoding, m_option->m_encoding);
|
|
m_config->writeEntry(rcRecursive, m_option->m_recursive);
|
|
m_config->writeEntry(rcCaseSensitive, m_option->m_caseSensitive);
|
|
m_config->writeEntry(rcVariables, m_option->m_variables);
|
|
m_config->writeEntry(rcRegularExpressions, m_option->m_regularExpressions);
|
|
|
|
m_config->writeEntry(rcFollowSymLinks, m_option->m_followSymLinks);
|
|
m_config->writeEntry(rcHaltOnFirstOccur, m_option->m_haltOnFirstOccur);
|
|
|
|
m_config->writeEntry(rcIgnoreHidden, m_option->m_ignoreHidden);
|
|
m_config->writeEntry(rcIgnoreFiles, m_option->m_ignoreFiles);
|
|
|
|
m_config->setGroup("Notification Messages");
|
|
m_config->writeEntry(rcNotifyOnErrors, m_option->m_notifyOnErrors);
|
|
if(m_config->readEntry(rcDontAskAgain,"no") == "yes")
|
|
m_config->writeEntry(rcAskConfirmReplace, false);
|
|
else
|
|
m_config->writeEntry(rcAskConfirmReplace, m_option->m_askConfirmReplace);
|
|
|
|
m_config->sync();
|
|
}
|
|
|
|
void TDEFileReplacePart::saveFileSizeOptions()
|
|
{
|
|
m_config->setGroup("Size options");
|
|
|
|
m_config->writeEntry(rcMaxFileSize, m_option->m_maxSize);
|
|
m_config->writeEntry(rcMinFileSize, m_option->m_minSize);
|
|
|
|
m_config->sync();
|
|
}
|
|
|
|
void TDEFileReplacePart::saveDateAccessOptions()
|
|
{
|
|
m_config->setGroup("Access options");
|
|
|
|
m_config->writeEntry(rcValidAccessDate, m_option->m_dateAccess);
|
|
m_config->writeEntry(rcMinDate, m_option->m_minDate);
|
|
m_config->writeEntry(rcMaxDate, m_option->m_maxDate);
|
|
|
|
m_config->sync();
|
|
}
|
|
|
|
void TDEFileReplacePart::saveOwnerOptions()
|
|
{
|
|
m_config->setGroup("Owner options");
|
|
|
|
TQString list;
|
|
if(m_option->m_ownerUserIsChecked)
|
|
list = "true,";
|
|
else
|
|
list = "false,";
|
|
|
|
list += m_option->m_ownerUserType +
|
|
"," +
|
|
m_option->m_ownerUserBool;
|
|
if(!m_option->m_ownerUserValue.isEmpty())
|
|
list += "," + m_option->m_ownerUserValue;
|
|
|
|
m_config->writeEntry(rcOwnerUser,list);
|
|
|
|
if(m_option->m_ownerGroupIsChecked)
|
|
list = "true,";
|
|
else
|
|
list = "false,";
|
|
|
|
list += m_option->m_ownerGroupType +
|
|
"," +
|
|
m_option->m_ownerGroupBool;
|
|
if(!m_option->m_ownerGroupValue.isEmpty())
|
|
list += "," + m_option->m_ownerGroupValue;
|
|
|
|
m_config->writeEntry(rcOwnerGroup,list);
|
|
m_config->sync();
|
|
}
|
|
|
|
void TDEFileReplacePart::saveLocationsList()
|
|
{
|
|
m_config->setGroup("Directories");
|
|
#if KDE_IS_VERSION(3,1,3)
|
|
m_config->writePathEntry(rcDirectoriesList, m_option->m_directories);
|
|
#else
|
|
m_config->writeEntry(rcDirectoriesList, m_option->m_directories);
|
|
#endif
|
|
m_config->sync();
|
|
}
|
|
|
|
void TDEFileReplacePart::saveFiltersList()
|
|
{
|
|
m_config->setGroup("Filters");
|
|
m_config->writeEntry(rcFiltersList, m_option->m_filters);
|
|
m_config->sync();
|
|
}
|
|
|
|
void TDEFileReplacePart::saveBackupExtensionOptions()
|
|
{
|
|
m_config->setGroup("Options");
|
|
TQString bkOptions;
|
|
if(m_option->m_backup)
|
|
bkOptions = "true," + m_option->m_backupExtension;
|
|
else
|
|
bkOptions = "false," + m_option->m_backupExtension;
|
|
|
|
m_config->writeEntry(rcBackupExtension, bkOptions);
|
|
m_config->sync();
|
|
}
|
|
|
|
void TDEFileReplacePart::fileReplace()
|
|
{
|
|
TQString directoryName = m_option->m_directories[0];
|
|
TQDir d(directoryName);
|
|
d.setMatchAllDirs(true);
|
|
d.setFilter(m_optionMask);
|
|
|
|
TQString currentFilter = m_option->m_filters[0];
|
|
TQStringList filesList = d.entryList(currentFilter);
|
|
TQStringList::iterator filesIt;
|
|
int filesNumber = 0;
|
|
|
|
m_view->displayScannedFiles(filesNumber);
|
|
|
|
for (filesIt = filesList.begin(); filesIt != filesList.end() ; ++filesIt)
|
|
{
|
|
TQString fileName = (*filesIt);
|
|
|
|
// m_stop == true means that we pushed the stop button
|
|
if(m_stop)
|
|
break;
|
|
|
|
// Avoids files that not match requirements
|
|
if(!TDEFileReplaceLib::isAnAccessibleFile(d.canonicalPath(), fileName, m_option))
|
|
continue;
|
|
kapp->processEvents();
|
|
if(m_option->m_backup)
|
|
replaceAndBackup(d.canonicalPath(), fileName);
|
|
else
|
|
replaceAndOverwrite(d.canonicalPath(), fileName);
|
|
|
|
filesNumber++;
|
|
m_view->displayScannedFiles(filesNumber);
|
|
}
|
|
}
|
|
|
|
void TDEFileReplacePart::recursiveFileReplace(const TQString& directoryName, int& filesNumber, int depth)
|
|
{
|
|
//if m_stop == true then interrupts recursion
|
|
if(m_stop)
|
|
return;
|
|
else if (!depth > CIRCULAR_LINK_DETECTION_LEVEL)
|
|
{
|
|
if (!m_circ_ref_warning_shown)
|
|
{
|
|
KMessageBox::information(m_w,
|
|
i18n("It seems you have a circular reference in your file system."
|
|
"The search has been limited to this sublevel to prevent"
|
|
"TDEFileReplace from crashing."),
|
|
i18n("Circular reference detected"));
|
|
m_circ_ref_warning_shown = true;
|
|
}
|
|
return;
|
|
}
|
|
else
|
|
{
|
|
TQDir d(directoryName);
|
|
|
|
d.setMatchAllDirs(true);
|
|
d.setFilter(m_optionMask);
|
|
|
|
TQString currentFilter = m_option->m_filters[0];
|
|
TQStringList filesList = d.entryList(currentFilter);
|
|
TQStringList::iterator filesIt;
|
|
|
|
for(filesIt = filesList.begin(); filesIt != filesList.end(); ++filesIt)
|
|
{
|
|
//if m_stop == true then end for-loop
|
|
if(m_stop)
|
|
break;
|
|
|
|
TQString fileName = (*filesIt);
|
|
|
|
// Avoids files that not match requirements
|
|
if(!TDEFileReplaceLib::isAnAccessibleFile(d.canonicalPath(),fileName, m_option))
|
|
continue;
|
|
|
|
TQString filePath = d.canonicalPath()+"/"+fileName;
|
|
|
|
TQFileInfo qi(filePath);
|
|
|
|
m_view->displayScannedFiles(filesNumber);
|
|
kapp->processEvents();
|
|
|
|
//if filePath is a directory then recursion
|
|
if(qi.isDir())
|
|
recursiveFileReplace(filePath, filesNumber, depth+1);
|
|
else
|
|
{
|
|
if(m_option->m_backup)
|
|
replaceAndBackup(d.canonicalPath(), fileName);
|
|
else
|
|
replaceAndOverwrite(d.canonicalPath(), fileName);
|
|
|
|
filesNumber++;
|
|
m_view->displayScannedFiles(filesNumber);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void TDEFileReplacePart::replaceAndBackup(const TQString& currentDir, const TQString& oldFileName)
|
|
{
|
|
//Creates a path string
|
|
TQString oldPathString = currentDir+"/"+oldFileName;
|
|
|
|
TQFile currentFile(oldPathString);
|
|
if(!currentFile.open(IO_ReadOnly))
|
|
{
|
|
KMessageBox::information(m_w, i18n("<qt>Cannot open file <b>%1</b> for reading.</qt>").arg(oldFileName),TQString(), rcNotifyOnErrors);
|
|
return ;
|
|
}
|
|
TQTextStream currentStream(¤tFile);
|
|
if (m_option->m_encoding == "utf8")
|
|
currentStream.setEncoding(TQTextStream::UnicodeUTF8);
|
|
else
|
|
currentStream.setCodec(TQTextCodec::codecForName(m_option->m_encoding.ascii()));
|
|
TQString line = currentStream.read(),
|
|
backupLine = line;
|
|
|
|
TQString backupSize = TDEFileReplaceLib::formatFileSize(currentFile.size());
|
|
|
|
currentFile.close();
|
|
|
|
TQString backupExtension = m_option->m_backupExtension;
|
|
|
|
bool atLeastOneStringFound = false;
|
|
TDEListViewItem *item = 0;
|
|
int occurrence = 0;
|
|
|
|
replacingLoop(line, &item, atLeastOneStringFound, occurrence, m_option->m_regularExpressions, m_option->m_askConfirmReplace);
|
|
|
|
//If we are not performing a simulation creates a backup file
|
|
if(!m_option->m_simulation)
|
|
{
|
|
if(atLeastOneStringFound)
|
|
{
|
|
TDEIO::NetAccess::file_copy(KURL::fromPathOrURL(oldPathString), KURL::fromPathOrURL(oldPathString + backupExtension), -1, true);
|
|
}
|
|
}
|
|
|
|
if(!m_option->m_simulation)
|
|
{
|
|
if(atLeastOneStringFound)
|
|
{
|
|
TQFile newFile(oldPathString);
|
|
if(!newFile.open(IO_WriteOnly))
|
|
{
|
|
KMessageBox::information(m_w, i18n("<qt>Cannot open file <b>%1</b> for writing.</qt>").arg(oldFileName),TQString(), rcNotifyOnErrors);
|
|
return ;
|
|
}
|
|
TQTextStream newStream(&newFile);
|
|
if (m_option->m_encoding == "utf8")
|
|
newStream.setEncoding(TQTextStream::UnicodeUTF8);
|
|
else
|
|
newStream.setCodec(TQTextCodec::codecForName(m_option->m_encoding.ascii()));
|
|
newStream << line;
|
|
newFile.close();
|
|
}
|
|
}
|
|
|
|
if(!m_option->m_ignoreFiles)
|
|
atLeastOneStringFound = true;
|
|
|
|
TQFileInfo oldFileInfo(oldPathString);
|
|
|
|
if(atLeastOneStringFound && item/* && atLeastOneStringConfirmed*/)
|
|
{
|
|
TDEFileReplaceLib::setIconForFileEntry(item,currentDir+"/"+oldFileName);
|
|
item->setText(0,oldFileName);
|
|
item->setText(1,currentDir);
|
|
TQString newSize = TDEFileReplaceLib::formatFileSize(oldFileInfo.size());
|
|
if(!m_option->m_simulation)
|
|
{
|
|
item->setText(2, backupSize);
|
|
item->setText(3, newSize);
|
|
}
|
|
else
|
|
{
|
|
item->setText(2, backupSize);
|
|
item->setText(3, "-");
|
|
}
|
|
|
|
item->setText(4,TQString::number(occurrence,10));
|
|
item->setText(5,TQString("%1[%2]").arg(oldFileInfo.owner()).arg(oldFileInfo.ownerId()));
|
|
item->setText(6,TQString("%1[%2]").arg(oldFileInfo.group()).arg(oldFileInfo.groupId()));
|
|
}
|
|
}
|
|
|
|
void TDEFileReplacePart::replaceAndOverwrite(const TQString& currentDir, const TQString& oldFileName)
|
|
{
|
|
TQString oldPathString = currentDir+"/"+oldFileName;
|
|
TQFile oldFile(oldPathString);
|
|
TQFileInfo oldFileInfo(oldPathString);
|
|
|
|
if (!oldFile.open(IO_ReadOnly))
|
|
{
|
|
KMessageBox::information(m_w, i18n("<qt>Cannot open file <b>%1</b> for reading.</qt>").arg(oldFile.name()),TQString(), rcNotifyOnErrors);
|
|
return ;
|
|
}
|
|
|
|
TQString fileSizeBeforeReplacing = TDEFileReplaceLib::formatFileSize(oldFileInfo.size());
|
|
TDEListViewItem *item = 0;
|
|
|
|
TQTextStream oldStream( &oldFile );
|
|
if (m_option->m_encoding == "utf8")
|
|
oldStream.setEncoding(TQTextStream::UnicodeUTF8);
|
|
else
|
|
oldStream.setCodec(TQTextCodec::codecForName(m_option->m_encoding.ascii()));
|
|
TQString line = oldStream.read();
|
|
|
|
oldFile.close();
|
|
|
|
bool atLeastOneStringFound = false;
|
|
int occurrence = 0;
|
|
|
|
replacingLoop(line, &item, atLeastOneStringFound, occurrence, m_option->m_regularExpressions, m_option->m_askConfirmReplace);
|
|
|
|
|
|
if(!m_option->m_simulation)
|
|
{
|
|
if(atLeastOneStringFound)
|
|
{
|
|
TQFile newFile(oldPathString);
|
|
if(!newFile.open(IO_WriteOnly))
|
|
{
|
|
KMessageBox::information(m_w, i18n("<qt>Cannot open file <b>%1</b> for writing.</qt>").arg(newFile.name()),TQString(), rcNotifyOnErrors);
|
|
return ;
|
|
}
|
|
TQTextStream newStream( &newFile );
|
|
if (m_option->m_encoding == "utf8")
|
|
newStream.setEncoding(TQTextStream::UnicodeUTF8);
|
|
else
|
|
newStream.setCodec(TQTextCodec::codecForName(m_option->m_encoding.ascii()));
|
|
newStream << line;
|
|
newFile.close();
|
|
}
|
|
}
|
|
|
|
TQFileInfo nf(oldPathString);
|
|
TQString fileSizeAfterReplacing = TDEFileReplaceLib::formatFileSize(nf.size());
|
|
|
|
//if ignoreFiles == false then every files must be show
|
|
if(!m_option->m_ignoreFiles)
|
|
atLeastOneStringFound = true;
|
|
|
|
if(atLeastOneStringFound && item/*&& atLeastOneStringConfirmed*/)
|
|
{
|
|
TDEFileReplaceLib::setIconForFileEntry(item,currentDir+"/"+oldFileName);
|
|
item->setText(0,oldFileName);
|
|
item->setText(1,currentDir);
|
|
item->setText(2,fileSizeBeforeReplacing);
|
|
if(!m_option->m_simulation)
|
|
item->setText(3,fileSizeAfterReplacing);
|
|
else
|
|
item->setText(3,"-");
|
|
|
|
item->setText(4,TQString::number(occurrence,10));
|
|
item->setText(5,TQString("%1[%2]").arg(oldFileInfo.owner()).arg(oldFileInfo.ownerId()));
|
|
item->setText(6,TQString("%1[%2]").arg(oldFileInfo.group()).arg(oldFileInfo.groupId()));
|
|
}
|
|
}
|
|
|
|
void TDEFileReplacePart::replacingLoop(TQString& line, TDEListViewItem** item, bool& atLeastOneStringFound, int& occur, bool regularExpression, bool& askConfirmReplace)
|
|
{
|
|
KeyValueMap tempMap = m_replacementMap;
|
|
KeyValueMap::Iterator it;
|
|
TDEListView* rv = m_view->getResultsView();
|
|
|
|
for(it = tempMap.begin(); it != tempMap.end(); ++it)
|
|
{
|
|
if(m_stop)
|
|
break;
|
|
|
|
ResultViewEntry entry(it.key(), it.data(), regularExpression, m_option->m_caseSensitive);
|
|
while(entry.pos(line) != -1)
|
|
{
|
|
if(m_stop)
|
|
break;
|
|
|
|
if(askConfirmReplace)
|
|
{
|
|
int answer = KMessageBox::questionYesNo(0,
|
|
i18n("<qt>Do you want to replace the string <b>%1</b> with the string <b>%2</b>?</qt>").arg(it.key()).arg(it.data()),
|
|
i18n("Confirm Replace"),
|
|
i18n("Replace"),
|
|
i18n("Do Not Replace"),
|
|
rcDontAskAgain);
|
|
if(answer == KMessageBox::Yes)
|
|
{
|
|
atLeastOneStringFound = true;
|
|
TQString msg = entry.message(entry.capturedText(line),
|
|
entry.lineNumber(line),
|
|
entry.columnNumber(line));
|
|
|
|
if(!*item)
|
|
*item = new TDEListViewItem(rv);
|
|
TDEListViewItem* tempItem = new TDEListViewItem(*item);
|
|
tempItem->setMultiLinesEnabled(true);
|
|
tempItem->setText(0,msg);
|
|
occur ++;
|
|
entry.updateLine(line);
|
|
entry.incPos();
|
|
}
|
|
else
|
|
{
|
|
entry.incPos();
|
|
}
|
|
if(dontAskAgain()) askConfirmReplace = false;
|
|
}
|
|
else
|
|
{
|
|
atLeastOneStringFound = true;
|
|
TQString msg = entry.message(entry.capturedText(line),
|
|
entry.lineNumber(line),
|
|
entry.columnNumber(line));
|
|
|
|
if(!*item)
|
|
*item = new TDEListViewItem(rv);
|
|
TDEListViewItem* tempItem = new TDEListViewItem(*item);
|
|
tempItem->setMultiLinesEnabled(true);
|
|
tempItem->setText(0,msg);
|
|
occur ++;
|
|
entry.updateLine(line);
|
|
entry.incPos();
|
|
}
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
void TDEFileReplacePart::fileSearch(const TQString& directoryName, const TQString& filters)
|
|
{
|
|
TQDir d(directoryName);
|
|
|
|
d.setMatchAllDirs(true);
|
|
d.setFilter(m_optionMask);
|
|
|
|
TQStringList filesList = d.entryList(filters);
|
|
TQString filePath = d.canonicalPath();
|
|
TQStringList::iterator filesIt;
|
|
uint filesNumber = 0;
|
|
|
|
m_view->displayScannedFiles(filesNumber);
|
|
|
|
for (filesIt = filesList.begin(); filesIt != filesList.end() ; ++filesIt)
|
|
{
|
|
// We pushed stop button
|
|
if(m_stop)
|
|
break;
|
|
|
|
TQString fileName = (*filesIt);
|
|
|
|
// Avoids files that not match
|
|
if(!TDEFileReplaceLib::isAnAccessibleFile(filePath, fileName, m_option))
|
|
continue;
|
|
|
|
TQFileInfo fileInfo(filePath+"/"+fileName);
|
|
if(fileInfo.isDir())
|
|
continue;
|
|
kapp->processEvents();
|
|
search(filePath, fileName);
|
|
filesNumber++;
|
|
m_view->displayScannedFiles(filesNumber);
|
|
}
|
|
}
|
|
|
|
void TDEFileReplacePart::recursiveFileSearch(const TQString& directoryName, const TQString& filters, uint& filesNumber, int depth)
|
|
{
|
|
// if m_stop == true then interrupt recursion
|
|
if(m_stop)
|
|
return;
|
|
else if (depth > CIRCULAR_LINK_DETECTION_LEVEL)
|
|
{
|
|
if (!m_circ_ref_warning_shown)
|
|
{
|
|
KMessageBox::information(m_w,
|
|
i18n("It seems you have a circular reference in your file system. "
|
|
"The search has been limited to this sublevel to prevent "
|
|
"TDEFileReplace from crashing."),
|
|
i18n("Circular reference detected"));
|
|
m_circ_ref_warning_shown = true;
|
|
}
|
|
return;
|
|
}
|
|
else
|
|
{
|
|
TQDir d(directoryName);
|
|
|
|
d.setMatchAllDirs(true);
|
|
d.setFilter(m_optionMask);
|
|
|
|
TQStringList filesList = d.entryList(filters);
|
|
TQString filePath = d.canonicalPath();
|
|
TQStringList::iterator filesIt;
|
|
|
|
for(filesIt = filesList.begin(); filesIt != filesList.end(); ++filesIt)
|
|
{
|
|
// stop polling
|
|
if(m_stop)
|
|
break;
|
|
|
|
TQString fileName = (*filesIt);
|
|
// Avoids files that not match
|
|
if(!TDEFileReplaceLib::isAnAccessibleFile(filePath, fileName, m_option))
|
|
continue;
|
|
|
|
// Composes file path string
|
|
TQFileInfo fileInfo(filePath+"/"+fileName);
|
|
|
|
m_view->displayScannedFiles(filesNumber);
|
|
|
|
kapp->processEvents();
|
|
// Searchs recursively if "filePath" is a directory
|
|
if(fileInfo.isDir())
|
|
recursiveFileSearch(filePath+"/"+fileName, filters, filesNumber, depth+1);
|
|
else
|
|
{
|
|
search(filePath, fileName);
|
|
filesNumber++;
|
|
m_view->displayScannedFiles(filesNumber);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void TDEFileReplacePart::search(const TQString& currentDir, const TQString& fileName)
|
|
{
|
|
TQFile file(currentDir+"/"+fileName);
|
|
|
|
if(!file.open(IO_ReadOnly))
|
|
{
|
|
KMessageBox::information(m_w, i18n("<qt>Cannot open file <b>%1</b> for reading.</qt>").arg(fileName), TQString(), rcNotifyOnErrors);
|
|
return ;
|
|
}
|
|
// Creates a stream with the file
|
|
TQTextStream stream( &file );
|
|
if (m_option->m_encoding == "utf8")
|
|
stream.setEncoding(TQTextStream::UnicodeUTF8);
|
|
else
|
|
stream.setCodec(TQTextCodec::codecForName(m_option->m_encoding.ascii()));
|
|
TQString line = stream.read();
|
|
file.close();
|
|
|
|
TQFileInfo fileInfo(currentDir+"/"+fileName);
|
|
|
|
TDEListViewItem *item = 0;
|
|
|
|
//Counts occurrences
|
|
int occurrence = 0;
|
|
|
|
//This map contains strings to search
|
|
KeyValueMap tempMap = m_replacementMap;
|
|
//If no strings has been found, then no lines will be added to the result view
|
|
bool atLeastOneStringFound = false;
|
|
|
|
KeyValueMap::Iterator it = tempMap.begin();
|
|
|
|
TDEListView* rv = m_view->getResultsView();
|
|
|
|
while(it != tempMap.end())
|
|
{
|
|
//stop polling
|
|
if(m_stop)
|
|
break;
|
|
|
|
TQString key = it.key();
|
|
TQString strKey;
|
|
TQRegExp rxKey;
|
|
|
|
if(m_option->m_regularExpressions)
|
|
rxKey = TQRegExp("("+key+")", m_option->m_caseSensitive, false);
|
|
else
|
|
strKey = key;
|
|
/* If this option is true then for any string in
|
|
* the map we search for the first match*/
|
|
if(m_option->m_haltOnFirstOccur)
|
|
{
|
|
int pos;
|
|
|
|
if(m_option->m_regularExpressions)
|
|
pos = line.find(rxKey);
|
|
else
|
|
pos = line.find(strKey, 0 ,m_option->m_caseSensitive);
|
|
|
|
if(pos != -1)
|
|
{
|
|
atLeastOneStringFound = true;
|
|
int lineNumber = line.mid(0,pos).contains('\n')+1;
|
|
int columnNumber = pos - line.findRev('\n',pos);
|
|
|
|
if (!item)
|
|
item = new TDEListViewItem(rv);
|
|
|
|
TDEListViewItem* tempItem= new TDEListViewItem(item);
|
|
TQString msg,
|
|
capturedText;
|
|
|
|
if(m_option->m_regularExpressions)
|
|
capturedText = rxKey.cap(1);
|
|
else
|
|
capturedText = line.mid(pos,strKey.length());
|
|
|
|
msg = i18n(" Line:%2, Col:%3 - \"%1\"").arg(capturedText).arg(TQString::number(lineNumber,10)).arg(TQString::number(columnNumber,10));
|
|
tempItem->setMultiLinesEnabled(true);
|
|
tempItem->setText(0,msg);
|
|
occurrence = 1;
|
|
}
|
|
}// ends m_option->m_haltOnFirstOccur if-block
|
|
else
|
|
{
|
|
/* This point of the code is reached when we must search for all
|
|
* occurrences of all the strings*/
|
|
|
|
int pos = 0;
|
|
if(m_option->m_regularExpressions)
|
|
pos = rxKey.search(line,pos);
|
|
else
|
|
pos = line.find(strKey, pos ,m_option->m_caseSensitive);
|
|
|
|
while(pos != -1)
|
|
{
|
|
//stop polling
|
|
if(m_stop)
|
|
break;
|
|
|
|
atLeastOneStringFound = true;
|
|
TQString msg,
|
|
capturedText;
|
|
int lineNumber = line.mid(0,pos).contains('\n')+1;
|
|
int columnNumber = pos - line.findRev('\n',pos);
|
|
|
|
if(m_option->m_regularExpressions)
|
|
{
|
|
capturedText = rxKey.cap(1);
|
|
pos = rxKey.search(line, pos+rxKey.matchedLength());
|
|
}
|
|
else
|
|
{
|
|
capturedText = line.mid(pos,strKey.length());
|
|
pos = line.find(strKey,pos+strKey.length());
|
|
}
|
|
|
|
msg = i18n(" Line:%2, Col:%3 - \"%1\"").arg(capturedText).arg(TQString::number(lineNumber,10)).arg(TQString::number(columnNumber,10));
|
|
|
|
if(!item)
|
|
item = new TDEListViewItem(rv);
|
|
TDEListViewItem* tempItem = new TDEListViewItem(item);
|
|
tempItem->setMultiLinesEnabled(true);
|
|
tempItem->setText(0,msg);
|
|
occurrence++;
|
|
//we push stop button
|
|
if(m_stop)
|
|
break;
|
|
}
|
|
}
|
|
//Advances of one position in the strings map
|
|
++it;
|
|
|
|
//we push stop button
|
|
if(m_stop)
|
|
break;
|
|
}
|
|
|
|
//if ignoreFiles == false then every files must be show
|
|
if(!m_option->m_ignoreFiles)
|
|
atLeastOneStringFound = true;
|
|
|
|
if(atLeastOneStringFound && item)
|
|
{
|
|
TDEFileReplaceLib::setIconForFileEntry(item,currentDir+"/"+fileName);
|
|
item->setText(0,fileName);
|
|
item->setText(1,currentDir);
|
|
item->setText(2,TDEFileReplaceLib::formatFileSize(fileInfo.size()));
|
|
item->setText(3,TQString::number(occurrence,10));
|
|
item->setText(4,TQString("%1[%2]").arg(fileInfo.owner()).arg(fileInfo.ownerId()));
|
|
item->setText(5,TQString("%1[%2]").arg(fileInfo.group()).arg(fileInfo.groupId()));
|
|
}
|
|
}
|
|
|
|
void TDEFileReplacePart::loadViewContent()
|
|
{
|
|
/* Maps the content of the strings view to a TQMap */
|
|
KeyValueMap tempMap;
|
|
CommandEngine command;
|
|
|
|
TQListViewItemIterator itlv(m_view->getStringsView());
|
|
while(itlv.current())
|
|
{
|
|
TQListViewItem *item = itlv.current();
|
|
if(m_option->m_variables)
|
|
tempMap[item->text(0)] = command.variableValue(item->text(1));
|
|
else
|
|
tempMap[item->text(0)] = item->text(1);
|
|
++itlv;
|
|
}
|
|
m_replacementMap = tempMap;
|
|
}
|
|
|
|
void TDEFileReplacePart::loadRulesFile(const TQString& fileName)
|
|
{
|
|
/* Loads a file with kfr extension.
|
|
* creates a xml document and browses it*/
|
|
TQDomDocument doc("mydocument");
|
|
TQFile file(fileName);
|
|
TDEListView* sv = m_view->getStringsView();
|
|
|
|
if(!file.open(IO_ReadOnly))
|
|
{
|
|
KMessageBox::error(m_w, i18n("<qt>Cannot open the file <b>%1</b> and load the string list.</qt>").arg(fileName));
|
|
return ;
|
|
}
|
|
|
|
if(!doc.setContent(&file))
|
|
{
|
|
file.close();
|
|
|
|
KMessageBox::information(m_w, i18n("<qt>File <b>%1</b> seems not to be written in new kfr format. Remember that the old kfr format will be soon abandoned. You can convert your old rules files by simply saving them with tdefilereplace.</qt>").arg(fileName),i18n("Warning"));
|
|
|
|
TDEFileReplaceLib::convertOldToNewKFRFormat(fileName, sv);
|
|
|
|
return;
|
|
}
|
|
else
|
|
file.close();
|
|
|
|
//clears view
|
|
sv->clear();
|
|
|
|
TQDomElement docElem = doc.documentElement();
|
|
TQDomNode n = docElem.firstChild();
|
|
TQString searchAttribute = n.toElement().attribute("search").latin1();
|
|
|
|
KeyValueMap docMap;
|
|
|
|
if(searchAttribute.isNull() || searchAttribute.isEmpty())
|
|
{
|
|
int answer = KMessageBox::warningYesNo(m_w, i18n("<qt>The format of kfr files has been changed; attempting to load <b>%1</b>. Please see the KFilereplace manual for details. Do you want to load a search-and-replace list of strings?</qt>").arg(fileName),i18n("Warning"),i18n("Load"),i18n("Do Not Load"));
|
|
|
|
if(answer == KMessageBox::Yes)
|
|
searchAttribute = "false";
|
|
else
|
|
searchAttribute = "true";
|
|
}
|
|
//Verifies the search mode
|
|
if(searchAttribute == "true")
|
|
m_option->m_searchingOnlyMode = true;
|
|
else
|
|
m_option->m_searchingOnlyMode = false;
|
|
|
|
//Refreshes the view appearances
|
|
m_view->changeView(m_option->m_searchingOnlyMode);
|
|
//Goes to next tag
|
|
n = n.nextSibling();
|
|
//Reads the string list
|
|
while(!n.isNull())
|
|
{
|
|
TQDomElement e = n.toElement(); // tries to convert the node to an element.
|
|
if(!e.isNull())
|
|
{
|
|
TQString oldString = e.firstChild().toElement().text(),
|
|
newString = e.lastChild().toElement().text();
|
|
docMap[oldString] = newString;
|
|
}
|
|
n = n.nextSibling();
|
|
}
|
|
|
|
// Adds file to "load strings form file" menu
|
|
TQStringList fileList = m_option->m_recentStringFileList;
|
|
if(!fileList.contains(fileName))
|
|
{
|
|
fileList.append(fileName);
|
|
((TDERecentFilesAction* ) actionCollection()->action("strings_load_recent"))->setItems(fileList);
|
|
m_option->m_recentStringFileList = fileList;
|
|
}
|
|
|
|
m_view->changeView(m_option->m_searchingOnlyMode);
|
|
|
|
m_view->loadMap(docMap);
|
|
|
|
//resetActions();
|
|
}
|
|
|
|
bool TDEFileReplacePart::launchNewProjectDialog(const KURL & startURL)
|
|
{
|
|
if(!startURL.isEmpty())
|
|
m_option->m_directories.prepend(startURL.path());
|
|
|
|
/* This dlg reads options from m_option, then execs, finally returns options.*/
|
|
KNewProjectDlg dlg(m_option);
|
|
|
|
if(!dlg.exec())
|
|
return false;
|
|
|
|
dlg.saveRCOptions();
|
|
|
|
m_config->sync();
|
|
|
|
slotQuickStringsAdd();
|
|
|
|
m_view->updateOptions(m_option);
|
|
|
|
resetActions();
|
|
|
|
return true;
|
|
}
|
|
|
|
void TDEFileReplacePart::setOptionMask()
|
|
{
|
|
m_optionMask |= TQDir::Dirs;
|
|
|
|
if(!m_option->m_ignoreHidden)
|
|
m_optionMask |= TQDir::Hidden;
|
|
|
|
if(!m_option->m_followSymLinks)
|
|
m_optionMask |= TQDir::NoSymLinks;
|
|
}
|
|
|
|
bool TDEFileReplacePart::checkBeforeOperation()
|
|
{
|
|
loadViewContent();
|
|
TDEListView* sv = m_view->getStringsView();
|
|
|
|
// Checks if there are strings to replace (not need in search operation)
|
|
if (sv->childCount() == 0)
|
|
{
|
|
KMessageBox::error(m_w, i18n("There are no strings to search and replace."));
|
|
return false;
|
|
}
|
|
|
|
// Checks if the main directory can be accessed
|
|
TQString currentDirectory = m_option->m_directories[0];
|
|
TQDir dir;
|
|
|
|
dir.setPath(currentDirectory);
|
|
TQString directory = dir.absPath();
|
|
|
|
if(!dir.exists())
|
|
{
|
|
KMessageBox::error(m_w, i18n("<qt>The main folder of the project <b>%1</b> does not exist.</qt>").arg(directory));
|
|
return false;
|
|
}
|
|
|
|
TQFileInfo dirInfo(directory);
|
|
if(!(dirInfo.isReadable() && dirInfo.isExecutable())
|
|
|| (!m_option->m_searchingOnlyMode && !m_option->m_simulation && !(dirInfo.isWritable())))
|
|
{
|
|
KMessageBox::error(m_w, i18n("<qt>Access denied in the main folder of the project:<br><b>%1</b></qt>").arg(directory));
|
|
return false;
|
|
}
|
|
|
|
// Clears the list view
|
|
m_view->getResultsView()->clear();
|
|
|
|
return true;
|
|
}
|
|
|
|
bool TDEFileReplacePart::dontAskAgain()
|
|
{
|
|
m_config->setGroup("Notification Messages");
|
|
TQString dontAskAgain = m_config->readEntry(rcDontAskAgain, "no");
|
|
if(dontAskAgain == "yes")
|
|
return true;
|
|
else
|
|
return false;
|
|
}
|
|
|
|
void TDEFileReplacePart::whatsThis()
|
|
{
|
|
actionCollection()->action("options_backup")->setWhatsThis(optionsBackupWhatthis);
|
|
actionCollection()->action("options_case")->setWhatsThis(optionsCaseWhatthis);
|
|
actionCollection()->action("options_var")->setWhatsThis(optionsVarWhatthis);
|
|
actionCollection()->action("options_recursive")->setWhatsThis(optionsRecursiveWhatthis);
|
|
actionCollection()->action("options_regularexpressions")->setWhatsThis(optionsRegularExpressionsWhatthis);
|
|
}
|
|
|
|
#include "tdefilereplacepart.moc"
|