kparametereditor.cpp 10.2 KB
Newer Older
1 2 3
/*
* KmPlot - a math. function plotter for the KDE-Desktop
*
4
* Copyright (C) 2004  Fredrik Edemar <f_edemar@linux.se>
5
*               2006  David Saxton <david@bluehaze.org>
6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
*               
* This file is part of the KDE Project.
* KmPlot is part of the KDE-EDU Project.
*
* 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
Dirk Mueller's avatar
Dirk Mueller committed
22
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
23 24 25
*
*/

Peter Hedlund's avatar
Peter Hedlund committed
26
#include "kparametereditor.h"
27 28

#include <kdebug.h>
29
#include <kfiledialog.h>
30
#include <kinputdialog.h>
31
#include <kio/netaccess.h>
32 33
#include <kmessagebox.h>
#include <kpushbutton.h>
Jaison Lee's avatar
Jaison Lee committed
34
#include <ktemporaryfile.h>
35
#include <kurl.h>
36 37
#include <qfile.h>
#include <qtextstream.h>
38
#include <QList>
39
#include <QListWidget>
40

41 42
#include <assert.h>

43 44
class ParameterValueList;

45
KParameterEditor::KParameterEditor( QList<Value> *l, QWidget *parent )
Fredrik Edemar's avatar
Fredrik Edemar committed
46
	: KDialog( parent ),
47
	  m_parameter(l)
48
{
Pino Toscano's avatar
Pino Toscano committed
49 50 51
	setCaption( i18n( "Parameter Editor" ) );
	setButtons( Ok | Cancel );

52
	m_mainWidget = new QParameterEditor( this );
53
	m_mainWidget->layout()->setMargin( 0 );
54
	setMainWidget( m_mainWidget );
55
	
Christoph Feck's avatar
Christoph Feck committed
56 57 58 59 60 61
	m_mainWidget->cmdNew->setIcon( QIcon::fromTheme("document-new" ) );
	m_mainWidget->cmdDelete->setIcon( QIcon::fromTheme("edit-delete" ) );
	m_mainWidget->moveUp->setIcon( QIcon::fromTheme("go-up") );
	m_mainWidget->moveDown->setIcon( QIcon::fromTheme("go-down") );
	m_mainWidget->cmdImport->setIcon( QIcon::fromTheme("document-open") );
	m_mainWidget->cmdExport->setIcon( QIcon::fromTheme("document-save") );
62 63 64
	
	m_mainWidget->list->setFocusPolicy( Qt::NoFocus );
	
Laurent Montel's avatar
Laurent Montel committed
65 66
	connect(m_mainWidget->value, &EquationEdit::upPressed, this, &KParameterEditor::prev);
	connect(m_mainWidget->value, &EquationEdit::downPressed, this, &KParameterEditor::next);
67
	
68
	foreach ( const Value &v, *m_parameter )
69
		m_mainWidget->list->addItem( v.expression() );
70
	
Laurent Montel's avatar
Laurent Montel committed
71 72 73 74 75 76 77
	connect(m_mainWidget->cmdNew, &QPushButton::clicked, this, &KParameterEditor::cmdNew_clicked);
	connect(m_mainWidget->cmdDelete, &QPushButton::clicked, this, &KParameterEditor::cmdDelete_clicked);
	connect(m_mainWidget->moveUp, &QPushButton::clicked, this, &KParameterEditor::moveUp);
	connect(m_mainWidget->moveDown, &QPushButton::clicked, this, &KParameterEditor::moveDown);
	connect(m_mainWidget->cmdImport, &QPushButton::clicked, this, &KParameterEditor::cmdImport_clicked);
	connect(m_mainWidget->cmdExport, &QPushButton::clicked, this, &KParameterEditor::cmdExport_clicked);
	connect(m_mainWidget->list, &QListWidget::currentItemChanged, this, &KParameterEditor::selectedConstantChanged);
78
	
Laurent Montel's avatar
Laurent Montel committed
79 80
	connect(m_mainWidget->value, &EquationEdit::textEdited, this, &KParameterEditor::saveCurrentValue);
	connect(m_mainWidget->value, &EquationEdit::textChanged, this, &KParameterEditor::checkValueValid);
81
	connect( m_mainWidget->value, SIGNAL( returnPressed() ), m_mainWidget->cmdNew, SLOT( animateClick() ) );
82 83
	
	checkValueValid();
84
	
85
	m_mainWidget->value->setFocus();
86 87 88 89
}

KParameterEditor::~KParameterEditor()
{
90 91
}

92

93 94 95
void KParameterEditor::accept()
{
	kDebug() << "saving\n";
96
	m_parameter->clear();
97
	QString item_text;
98
	for ( int i = 0; i < m_mainWidget->list->count(); i++ )
99
	{
100
		item_text = m_mainWidget->list->item(i)->text();
101
		if ( !item_text.isEmpty() )
102 103 104 105 106
		{
			Value value;
			if ( value.updateExpression( item_text ) )
				m_parameter->append( value );
		}
107
	}
108 109
	
	KDialog::accept();
110 111
}

112

113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136
void KParameterEditor::moveUp()
{
	int current = m_mainWidget->list->currentRow();
	
	if ( current == 0 )
		return;
	
	QListWidgetItem * item = m_mainWidget->list->takeItem( current-1 );
	m_mainWidget->list->insertItem( current, item );
}


void KParameterEditor::moveDown()
{
	int current = m_mainWidget->list->currentRow();
	
	if ( current == m_mainWidget->list->count() - 1 )
		return;
	
	QListWidgetItem * item = m_mainWidget->list->takeItem( current+1 );
	m_mainWidget->list->insertItem( current, item );
}


137 138
void KParameterEditor::cmdNew_clicked()
{
139
	QListWidgetItem * item = new QListWidgetItem( m_mainWidget->list );
140
	item->setText( "0" );
141 142
	m_mainWidget->list->setCurrentItem( item );
	m_mainWidget->value->setFocus();
143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161
	m_mainWidget->value->selectAll();
}


void KParameterEditor::prev()
{
	int current = m_mainWidget->list->currentRow();
	if ( current > 0 )
		m_mainWidget->list->setCurrentRow( current-1 );
}


void KParameterEditor::next()
{
	int current = m_mainWidget->list->currentRow();
	if ( current < m_mainWidget->list->count()-1 )
		m_mainWidget->list->setCurrentRow( current+1 );
	else
		cmdNew_clicked();
162 163
}

164 165

void KParameterEditor::selectedConstantChanged( QListWidgetItem * current )
166
{
167
	m_mainWidget->cmdDelete->setEnabled( current != 0 );
Peter Hedlund's avatar
Peter Hedlund committed
168
	m_mainWidget->value->setText( current ? current->text() : QString() );
169
	m_mainWidget->value->selectAll();
170 171
}

172

173 174
void KParameterEditor::cmdDelete_clicked()
{
175 176 177 178 179 180 181 182 183
	QListWidgetItem * item = m_mainWidget->list->currentItem();
	if ( !item )
		return;
	
	m_mainWidget->value->clear();
	m_mainWidget->list->takeItem( m_mainWidget->list->currentRow() );
	delete item;
	
	m_mainWidget->cmdDelete->setEnabled( m_mainWidget->list->currentItem() != 0 );
184 185
}

186 187 188 189 190 191 192 193 194 195 196 197 198 199 200

void KParameterEditor::saveCurrentValue()
{
	QListWidgetItem * current = m_mainWidget->list->currentItem();
	if ( !current )
		current = new QListWidgetItem( m_mainWidget->list );
	
	current->setText( m_mainWidget->value->text() );
	m_mainWidget->list->setCurrentItem( current );
}


bool KParameterEditor::checkValueValid()
{
	QString valueText = m_mainWidget->value->text();
201 202 203
	Parser::Error error;
	(double) XParser::self()->eval( valueText, & error );
	bool valid = (error == Parser::ParseSuccess);
204 205 206 207 208
	m_mainWidget->valueInvalidLabel->setVisible( !valueText.isEmpty() && !valid );
	return valid;
}


209 210
void KParameterEditor::cmdImport_clicked()
{
211
	QUrl url = KFileDialog::getOpenUrl(QUrl(),i18n("*.txt|Plain Text File "));
212
	if ( url.isEmpty() )
213
		return;
214

215
        if (!KIO::NetAccess::exists(url, KIO::NetAccess::SourceSide, this) )
216
        {
217
			KMessageBox::sorry(0,i18n("The file does not exist."));
218 219
                return;
        }
220

221
	bool verbose = false;
222 223 224 225 226 227
        QFile file;
        QString tmpfile;
        if ( !url.isLocalFile() )
        {
                if ( !KIO::NetAccess::download(url, tmpfile, this) )
                {
228
					KMessageBox::sorry(0,i18n("An error appeared when opening this file"));
229 230
                        return;
                }
231
                file.setFileName(tmpfile);
232 233
        }
        else
234
                file.setFileName(url.toLocalFile() );
235
	
Laurent Montel's avatar
Laurent Montel committed
236
	if ( file.open(QIODevice::ReadOnly) )
237 238 239
	{
		QTextStream stream(&file);
		QString line;
240
		for( int i=1; !stream.atEnd();i++ )
241 242
		{
			line = stream.readLine();
243 244
			if (line.isEmpty())
				continue;
245 246 247 248
			
			Parser::Error error;
			XParser::self()->eval( line, & error );
			if ( error == Parser::ParseSuccess )
249
			{
250 251
				if ( !checkTwoOfIt(line) )
				{
252
					m_mainWidget->list->addItem(line);
253
				}
254
			}
255 256
			else if ( !verbose)
			{
257
				if ( KMessageBox::warningContinueCancel(this,i18n("Line %1 is not a valid parameter value and will therefore not be included. Do you want to continue?", i) ) == KMessageBox::Cancel)
258 259
				{
					file.close();
260
                                        KIO::NetAccess::removeTempFile( tmpfile );
261 262
					return;
				}
263
				else if (KMessageBox::warningYesNo(this,i18n("Would you like to be informed about other lines that cannot be read?"), QString(), KGuiItem(i18n("Get Informed")), KGuiItem(i18n("Ignore Information")) ) == KMessageBox::No)
264 265
					verbose = true;
			}
266 267 268
		}
		file.close();
	}
269
	else
270
		KMessageBox::sorry(0,i18n("An error appeared when opening this file"));
271
        
272 273 274 275
        if ( !url.isLocalFile() )
                KIO::NetAccess::removeTempFile( tmpfile );
}

276

277 278
void KParameterEditor::cmdExport_clicked()
{
279
	if ( !m_mainWidget->list->count() )
280
                return;
281
	QUrl url = KFileDialog::getSaveUrl(QUrl(),i18n("*.txt|Plain Text File "));
282 283 284
        if ( url.isEmpty() )
                return;

285
        if( !KIO::NetAccess::exists( url, KIO::NetAccess::DestinationSide, this ) || KMessageBox::warningContinueCancel( this, i18n( "A file named \"%1\" already exists. Are you sure you want to continue and overwrite this file?", url.toDisplayString()), i18n( "Overwrite File?" ), KStandardGuiItem::overwrite() ) == KMessageBox::Continue )
286 287 288
        {
                if ( !url.isLocalFile() )
                {
Jaison Lee's avatar
Jaison Lee committed
289
                        KTemporaryFile tmpfile;
290

Jaison Lee's avatar
Jaison Lee committed
291 292 293 294 295 296 297 298 299 300 301 302 303 304
			if (tmpfile.open() )
			{
				QTextStream stream(&tmpfile);
				for ( int i = 0; i < m_mainWidget->list->count(); i++ )
				{
					QListWidgetItem * it = m_mainWidget->list->item( i );
					stream << it->text();
					if ( i < m_mainWidget->list->count()-1 )
						stream << endl; //only write a new line if there are more text
				}
				stream.flush();
			}
			else
				KMessageBox::sorry(0,i18n("An error appeared when saving this file"));
305
                        
Jaison Lee's avatar
Jaison Lee committed
306
                        if ( !KIO::NetAccess::upload(tmpfile.fileName(),url, this) )
307
                        {
Jaison Lee's avatar
Jaison Lee committed
308
				KMessageBox::sorry(0,i18n("An error appeared when saving this file"));
309 310 311 312 313
                                return;
                        }
                }
                else
                {
Jaison Lee's avatar
Jaison Lee committed
314
	                QFile file;
315 316
			kDebug() << "url.path()="<<url.toLocalFile();
			file.setFileName(url.toLocalFile());
Jaison Lee's avatar
Jaison Lee committed
317 318 319 320 321 322 323 324 325 326 327
			if (file.open( QIODevice::WriteOnly ) )
			{
				QTextStream stream(&file);
				for ( int i = 0; i < m_mainWidget->list->count(); i++ )
				{
					QListWidgetItem * it = m_mainWidget->list->item( i );
					stream << it->text();
					if ( i < m_mainWidget->list->count()-1 )
						stream << endl; //only write a new line if there are more text
				}
				file.close();
328 329
                        }
                        else
Jaison Lee's avatar
Jaison Lee committed
330
				KMessageBox::sorry(0,i18n("An error appeared when saving this file"));
331 332 333 334
                }
        }


335 336
}

337

338
bool KParameterEditor::checkTwoOfIt(const QString & text)
339
{
340
	return !m_mainWidget->list->findItems(text,Qt::MatchExactly).isEmpty();
341
}