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.
 
 
 

927 lines
19 KiB

/*
$Id$
kedit, a simple text editor for the KDE project
Copyright (C) 1997 Bernd Johannes Wuebben
wuebben@math.cornell.edu
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.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
KEdit, simple editor class, hacked version of the original by
*/
#include "keditcl.h"
#include <klocale.h>
#include <kapp.h>
//////////////////////////////////////////////////////////////////////////
//
// Find Methods
//
void KEdit::Search(){
if (replace_dialog)
if (replace_dialog->isVisible())
replace_dialog->hide();
if(!srchdialog){
srchdialog = new KEdSrch(0, "searchdialog");
connect(srchdialog,SIGNAL(search_signal()),this,SLOT(search_slot()));
connect(srchdialog,SIGNAL(search_done_signal()),this,SLOT(searchdone_slot()));
}
// If we already searched / replaced something before make sure it shows
// up in the find dialog line-edit.
QString string;
string = srchdialog->getText();
if(string.isEmpty())
srchdialog->setText(pattern);
this->deselect();
last_search = NONE;
this->clearFocus();
QPoint point = this->mapToGlobal (QPoint (0,0));
QRect pos = this->geometry();
srchdialog->setGeometry(point.x() + pos.width()/2 - srchdialog->width()/2,
point.y() + pos.height()/2 - srchdialog->height()/2,
srchdialog->width(),
srchdialog->height());
srchdialog->show();
srchdialog->result();
}
void KEdit::search_slot(){
int line, col;
if (!srchdialog)
return;
QString to_find_string = srchdialog->getText();
getCursorPosition(&line,&col);
// srchdialog->get_direction() is true if searching backward
if (last_search != NONE && srchdialog->get_direction()){
col = col - pattern.length() - 1 ;
}
again:
int result = doSearch(to_find_string, srchdialog->case_sensitive(),
FALSE, (!srchdialog->get_direction()),line,col);
if(result == 0){
if(!srchdialog->get_direction()){ // forward search
int query = QMessageBox::information(
this,
klocale->translate("Find"),
klocale->translate("End of document reached.\n"\
"Continue from the beginning?"),
klocale->translate("Yes"),
klocale->translate("No"),
"",
0,1);
if (query == 0){
line = 0;
col = 0;
goto again;
}
}
else{ //backward search
int query = QMessageBox::information(
this,
klocale->translate("Find"),
klocale->translate("Beginning of document reached.\n"\
"Continue from the end?"),
klocale->translate("Yes"),
klocale->translate("No"),
"",
0,1);
if (query == 0){
QString string = textLine( numLines() - 1 );
line = numLines() - 1;
col = string.length();
last_search = BACKWARD;
goto again;
}
}
}
else{
emit CursorPositionChanged();
}
}
void KEdit::searchdone_slot(){
if (!srchdialog)
return;
srchdialog->hide();
this->setFocus();
last_search = NONE;
}
int KEdit::doSearch(QString s_pattern, bool case_sensitive,
bool wildcard, bool forward, int line, int col){
(void) wildcard; // reserved for possible extension to regex
int i, length;
int pos = -1;
if(forward){
QString string;
for(i = line; i < numLines(); i++) {
string = textLine(i);
pos = string.find(s_pattern, i == line ? col : 0, case_sensitive);
if( pos != -1){
length = s_pattern.length();
setCursorPosition(i,pos,FALSE);
for(int l = 0 ; l < length; l++){
cursorRight(TRUE);
}
setCursorPosition( i , pos + length, TRUE );
pattern = s_pattern;
last_search = FORWARD;
return 1;
}
}
}
else{ // searching backwards
QString string;
for(i = line; i >= 0; i--) {
string = textLine(i);
int line_length = string.length();
pos = string.findRev(s_pattern, line == i ? col : line_length , case_sensitive);
if (pos != -1){
length = s_pattern.length();
if( ! (line == i && pos > col ) ){
setCursorPosition(i ,pos ,FALSE );
for(int l = 0 ; l < length; l++){
cursorRight(TRUE);
}
setCursorPosition(i ,pos + length ,TRUE );
pattern = s_pattern;
last_search = BACKWARD;
return 1;
}
}
}
}
return 0;
}
int KEdit::repeatSearch() {
if(!srchdialog)
return 0;
if(pattern.isEmpty()) // there wasn't a previous search
return 0;
search_slot();
this->setFocus();
return 1;
}
//////////////////////////////////////////////////////////////////////////
//
// Replace Methods
//
void KEdit::Replace(){
if (srchdialog)
if (srchdialog->isVisible())
srchdialog->hide();
if (!replace_dialog){
replace_dialog = new KEdReplace(0, "replace_dialog");
connect(replace_dialog,SIGNAL(find_signal()),this,SLOT(replace_search_slot()));
connect(replace_dialog,SIGNAL(replace_signal()),this,SLOT(replace_slot()));
connect(replace_dialog,SIGNAL(replace_all_signal()),this,SLOT(replace_all_slot()));
connect(replace_dialog,SIGNAL(replace_done_signal()),this,SLOT(replacedone_slot()));
}
QString string = replace_dialog->getText();
if(string.isEmpty())
replace_dialog->setText(pattern);
this->deselect();
last_replace = NONE;
this->clearFocus();
QPoint point = this->mapToGlobal (QPoint (0,0));
QRect pos = this->geometry();
replace_dialog->setGeometry(point.x() + pos.width()/2 - replace_dialog->width()/2,
point.y() + pos.height()/2 - replace_dialog->height()/2,
replace_dialog->width(),
replace_dialog->height());
replace_dialog->show();
replace_dialog->result();
}
void KEdit::replace_slot(){
if (!replace_dialog)
return;
if(!can_replace){
QApplication::beep();
return;
}
int line,col, length;
QString string = replace_dialog->getReplaceText();
length = string.length();
this->cut();
getCursorPosition(&line,&col);
insertAt(string,line,col);
setModified();
can_replace = FALSE;
setCursorPosition(line,col);
for( int k = 0; k < length; k++){
cursorRight(TRUE);
}
}
void KEdit::replace_all_slot(){
if (!replace_dialog)
return;
QString to_find_string = replace_dialog->getText();
getCursorPosition(&replace_all_line,&replace_all_col);
// replace_dialog->get_direction() is true if searching backward
if (last_replace != NONE && replace_dialog->get_direction()){
replace_all_col = replace_all_col - pattern.length() - 1 ;
}
deselect();
again:
setAutoUpdate(FALSE);
int result = 1;
while(result){
result = doReplace(to_find_string, replace_dialog->case_sensitive(),
FALSE, (!replace_dialog->get_direction()),
replace_all_line,replace_all_col,TRUE);
}
setAutoUpdate(TRUE);
update();
if(!replace_dialog->get_direction()){ // forward search
int query = QMessageBox::information(
this,
klocale->translate("Find"),
klocale->translate("End of document reached.\n"\
"Continue from the beginning?"),
klocale->translate("Yes"),
klocale->translate("No"),
"",
0,1);
if (query == 0){
replace_all_line = 0;
replace_all_col = 0;
goto again;
}
}
else{ //backward search
int query = QMessageBox::information(
this,
klocale->translate("Find"),
klocale->translate("Beginning of document reached.\n"\
"Continue from the end?"),
klocale->translate("Yes"),
klocale->translate("No"),
"",
0,1);
if (query == 0){
QString string = textLine( numLines() - 1 );
replace_all_line = numLines() - 1;
replace_all_col = string.length();
last_replace = BACKWARD;
goto again;
}
}
emit CursorPositionChanged();
}
void KEdit::replace_search_slot(){
int line, col;
if (!replace_dialog)
return;
QString to_find_string = replace_dialog->getText();
getCursorPosition(&line,&col);
// replace_dialog->get_direction() is true if searching backward
//printf("col %d length %d\n",col, pattern.length());
if (last_replace != NONE && replace_dialog->get_direction()){
col = col - pattern.length() -1;
if (col < 0 ) {
if(line !=0){
col = strlen(textLine(line - 1));
line --;
}
else{
int query = QMessageBox::information(
this,
klocale->translate("Replace"),
klocale->translate("Beginning of document reached.\n"\
"Continue from the end?"),
klocale->translate("Yes"),
klocale->translate("No"),
"",
0,1);
if (query == 0){
QString string = textLine( numLines() - 1 );
line = numLines() - 1;
col = string.length();
last_replace = BACKWARD;
}
}
}
}
again:
// printf("Col %d \n",col);
int result = doReplace(to_find_string, replace_dialog->case_sensitive(),
FALSE, (!replace_dialog->get_direction()), line, col, FALSE );
if(result == 0){
if(!replace_dialog->get_direction()){ // forward search
int query = QMessageBox::information(
this,
klocale->translate("Replace"),
klocale->translate("End of document reached.\n"\
"Continue from the beginning?"),
klocale->translate("Yes"),
klocale->translate("No"),
"",
0,1);
if (query == 0){
line = 0;
col = 0;
goto again;
}
}
else{ //backward search
int query = QMessageBox::information(
this,
klocale->translate("Replace"),
klocale->translate("Beginning of document reached.\n"\
"Continue from the end?"),
klocale->translate("Yes"),
klocale->translate("No"),
"",
0,1);
if (query == 0){
QString string = textLine( numLines() - 1 );
line = numLines() - 1;
col = string.length();
last_replace = BACKWARD;
goto again;
}
}
}
else{
emit CursorPositionChanged();
}
}
void KEdit::replacedone_slot(){
if (!replace_dialog)
return;
replace_dialog->hide();
// replace_dialog->clearFocus();
this->setFocus();
last_replace = NONE;
can_replace = FALSE;
}
int KEdit::doReplace(QString s_pattern, bool case_sensitive,
bool wildcard, bool forward, int line, int col, bool replace_all){
(void) wildcard; // reserved for possible extension to regex
int line_counter, length;
int pos = -1;
QString string;
QString stringnew;
QString replacement;
replacement = replace_dialog->getReplaceText();
line_counter = line;
replace_all_col = col;
if(forward){
int num_lines = numLines();
while (line_counter < num_lines){
string = "";
string = textLine(line_counter);
if (replace_all){
pos = string.find(s_pattern, replace_all_col, case_sensitive);
}
else{
pos = string.find(s_pattern, line_counter == line ? col : 0, case_sensitive);
}
if (pos == -1 ){
line_counter ++;
replace_all_col = 0;
replace_all_line = line_counter;
}
if( pos != -1){
length = s_pattern.length();
if(replace_all){ // automatic
stringnew = string.copy();
stringnew.replace(pos,length,replacement);
removeLine(line_counter);
insertLine(stringnew.data(),line_counter);
replace_all_col = replace_all_col + replacement.length();
replace_all_line = line_counter;
setModified();
}
else{ // interactive
setCursorPosition( line_counter , pos, FALSE );
for(int l = 0 ; l < length; l++){
cursorRight(TRUE);
}
setCursorPosition( line_counter , pos + length, TRUE );
pattern = s_pattern;
last_replace = FORWARD;
can_replace = TRUE;
return 1;
}
}
}
}
else{ // searching backwards
while(line_counter >= 0){
string = "";
string = textLine(line_counter);
int line_length = string.length();
if( replace_all ){
pos = string.findRev(s_pattern, replace_all_col , case_sensitive);
}
else{
pos = string.findRev(s_pattern,
line == line_counter ? col : line_length , case_sensitive);
}
if (pos == -1 ){
line_counter --;
if(line_counter >= 0){
string = "";
string = textLine(line_counter);
replace_all_col = string.length();
}
replace_all_line = line_counter;
}
if (pos != -1){
length = s_pattern.length();
if(replace_all){ // automatic
stringnew = string.copy();
stringnew.replace(pos,length,replacement);
removeLine(line_counter);
insertLine(stringnew.data(),line_counter);
replace_all_col = replace_all_col - replacement.length();
replace_all_line = line_counter;
setModified();
}
else{ // interactive
// printf("line_counter %d pos %d col %d\n",line_counter, pos,col);
if( ! (line == line_counter && pos > col ) ){
setCursorPosition(line_counter ,pos ,FALSE );
for(int l = 0 ; l < length; l++){
cursorRight(TRUE);
}
setCursorPosition(line_counter ,pos + length ,TRUE );
pattern = s_pattern;
last_replace = BACKWARD;
can_replace = TRUE;
return 1;
}
}
}
}
}
return 0;
}
////////////////////////////////////////////////////////////////////
//
// Find Dialog
//
KEdSrch::KEdSrch(QWidget *parent, const char *name)
: QDialog(parent, name,FALSE){
this->setFocusPolicy(QWidget::StrongFocus);
frame1 = new QGroupBox(klocale->translate("Find"), this, "frame1");
value = new QLineEdit( this, "value");
value->setFocus();
connect(value, SIGNAL(returnPressed()), this, SLOT(ok_slot()));
sensitive = new QCheckBox(klocale->translate("Case Sensitive"), this, "case");
direction = new QCheckBox(klocale->translate("Find Backwards"), this, "direction");
ok = new QPushButton(klocale->translate("Find"), this, "find");
connect(ok, SIGNAL(clicked()), this, SLOT(ok_slot()));
cancel = new QPushButton(klocale->translate("Done"), this, "cancel");
connect(cancel, SIGNAL(clicked()), this, SLOT(done_slot()));
// connect(cancel, SIGNAL(clicked()), this, SLOT(reject()));
setFixedSize(330, 130);
}
void KEdSrch::focusInEvent( QFocusEvent *)
{
value->setFocus();
//value->selectAll();
}
QString KEdSrch::getText() { return value->text(); }
void KEdSrch::setText(QString string){
value->setText(string);
}
void KEdSrch::done_slot(){
emit search_done_signal();
}
bool KEdSrch::case_sensitive(){
return sensitive->isChecked();
}
bool KEdSrch::get_direction(){
return direction->isChecked();
}
void KEdSrch::ok_slot(){
QString text;
text = value->text();
if (!text.isEmpty())
emit search_signal();
}
void KEdSrch::resizeEvent(QResizeEvent *){
frame1->setGeometry(5, 5, width() - 10, 80);
cancel->setGeometry(width() - 80, height() - 30, 70, 25);
ok->setGeometry(10, height() - 30, 70, 25);
value->setGeometry(20, 25, width() - 40, 25);
sensitive->setGeometry(20, 55, 110, 25);
direction->setGeometry(width()- 20 - 130, 55, 130, 25);
}
////////////////////////////////////////////////////////////////////
//
// Replace Dialog
//
KEdReplace::KEdReplace(QWidget *parent, const char *name)
: QDialog(parent, name,FALSE){
this->setFocusPolicy(QWidget::StrongFocus);
frame1 = new QGroupBox(klocale->translate("Find:"), this, "frame1");
value = new QLineEdit( this, "value");
value->setFocus();
connect(value, SIGNAL(returnPressed()), this, SLOT(ok_slot()));
replace_value = new QLineEdit( this, "replac_value");
connect(replace_value, SIGNAL(returnPressed()), this, SLOT(ok_slot()));
label = new QLabel(this,"Rlabel");
label->setText(klocale->translate("Replace with:"));
sensitive = new QCheckBox(klocale->translate("Case Sensitive"), this, "case");
sensitive->setChecked(TRUE);
direction = new QCheckBox(klocale->translate("Find Backwards")
, this, "direction");
ok = new QPushButton(klocale->translate("Find"), this, "find");
connect(ok, SIGNAL(clicked()), this, SLOT(ok_slot()));
replace = new QPushButton(klocale->translate("Replace"), this, "rep");
connect(replace, SIGNAL(clicked()), this, SLOT(replace_slot()));
replace_all = new QPushButton(klocale->translate("Replace All"), this, "repall");
connect(replace_all, SIGNAL(clicked()), this, SLOT(replace_all_slot()));
cancel = new QPushButton(klocale->translate("Done"), this, "cancel");
connect(cancel, SIGNAL(clicked()), this, SLOT(done_slot()));
setFixedSize(330, 180);
}
void KEdReplace::focusInEvent( QFocusEvent *){
value->setFocus();
// value->selectAll();
}
QString KEdReplace::getText() { return value->text(); }
QString KEdReplace::getReplaceText() { return replace_value->text(); }
void KEdReplace::setText(QString string) {
value->setText(string);
}
void KEdReplace::done_slot(){
emit replace_done_signal();
}
void KEdReplace::replace_slot(){
emit replace_signal();
}
void KEdReplace::replace_all_slot(){
emit replace_all_signal();
}
bool KEdReplace::case_sensitive(){
return sensitive->isChecked();
}
bool KEdReplace::get_direction(){
return direction->isChecked();
}
void KEdReplace::ok_slot(){
QString text;
text = value->text();
if (!text.isEmpty())
emit find_signal();
}
void KEdReplace::resizeEvent(QResizeEvent *){
frame1->setGeometry(5, 5, width() - 10, 135);
cancel->setGeometry(width() - 80, height() - 30, 70, 25);
ok->setGeometry(10, height() - 30, 70, 25);
replace->setGeometry(85, height() - 30, 70, 25);
replace_all->setGeometry(160, height() - 30, 85, 25);
value->setGeometry(20, 25, width() - 40, 25);
replace_value->setGeometry(20, 80, width() - 40, 25);
label->setGeometry(20,55,80,20);
sensitive->setGeometry(20, 110, 110, 25);
direction->setGeometry(width()- 20 - 130, 110, 130, 25);
}
KEdGotoLine::KEdGotoLine( QWidget *parent, const char *name)
: QDialog( parent, name, TRUE )
{
frame = new QGroupBox( klocale->translate("Goto Line"), this );
lineNum = new KIntLineEdit( this );
this->setFocusPolicy( QWidget::StrongFocus );
connect(lineNum, SIGNAL(returnPressed()), this, SLOT(accept()));
ok = new QPushButton(klocale->translate("Go"), this );
cancel = new QPushButton(klocale->translate("Cancel"), this );
connect(cancel, SIGNAL(clicked()), this, SLOT(reject()));
connect(ok, SIGNAL(clicked()), this, SLOT(accept()));
resize(300, 120);
}
void KEdGotoLine::selected(int)
{
accept();
}
void KEdGotoLine::resizeEvent(QResizeEvent *)
{
frame->setGeometry(5, 5, width() - 10, 80);
cancel->setGeometry(width() - 80, height() - 30, 70, 25);
ok->setGeometry(10, height() - 30, 70, 25);
lineNum->setGeometry(20, 35, width() - 40, 25);
}
void KEdGotoLine::focusInEvent( QFocusEvent *)
{
lineNum->setFocus();
lineNum->selectAll();
}
int KEdGotoLine::getLineNumber()
{
return lineNum->getValue();
}