--- branches/KDE/3.5/kdewebdev/kommander/editor/kommander-new.xml 2008/04/22 21:45:39 799932 +++ branches/KDE/3.5/kdewebdev/kommander/editor/kommander-new.xml 2009/10/15 07:34:24 1035469 @@ -116,6 +116,26 @@ array_indexedRemoveElements array_indexedInsertElements array_indexedToString + array_flipCopy + + + + matrix_fromString + matrix_toString + matrix_clear + matrix_rows + matrix_columnToArray + matrix_columnToIndexedArray + matrix_rowToArray + matrix_columns + matrix_rowKeys + matrix_columnKeys + matrix_removeRow + matrix_removeColumn + matrix_addRow + matrix_findRow + @@ -138,6 +158,11 @@ str_toint str_todouble str_round + str_sort + str_trim + str_padLeft + str_padRight + str_count @@ -171,6 +196,7 @@ else for + to function in select @@ -186,6 +212,12 @@ break continue exit + switch + and + or + not + step + with @@ -202,6 +234,7 @@ + @@ -213,6 +246,13 @@ + + + + + + + @@ -239,6 +279,7 @@ + @@ -256,6 +297,7 @@ + @@ -273,6 +315,8 @@ + + @@ -296,18 +340,18 @@ - - + + - + @@ -527,6 +571,7 @@ + @@ -535,6 +580,7 @@ + --- branches/KDE/3.5/kdewebdev/kommander/editor/mainwindow.cpp 2008/02/13 13:25:43 774537 +++ branches/KDE/3.5/kdewebdev/kommander/editor/mainwindow.cpp 2009/02/20 23:29:19 929242 @@ -463,6 +463,70 @@ } +void MainWindow::runForm4() +{ + if (previewing) + { + KMessageBox::information(this, i18n("There is a dialog already running."), i18n("Run")); + return; + } + FormWindow* form = activeForm(); + if (!form || !form->formFile()) + return; + + QObjectList *editors = queryList("AssocTextEditor"); + QObjectListIt it(*editors); + QObject *editor; + + while ((editor = it.current()) != 0L) + { + ++it; + static_cast(editor)->save(); + } + delete editors; + + if (form->formFile()->hasTempFileName()) + { + if (!form->formFile()->saveAs()) + return; + } + + m_fileName = form->formFile()->fileName(); + m_backupName = m_fileName + ".running"; + m_modified = form->formFile()->isModified(); + + bool readOnlyFile = !QFileInfo(m_fileName).isWritable(); + struct stat statbuf; + ::stat(m_fileName.local8Bit(), &statbuf); + if (!readOnlyFile && !KIO::NetAccess::file_copy(KURL::fromPathOrURL(m_fileName), KURL::fromPathOrURL(m_backupName), statbuf.st_mode, true)) + { + KMessageBox::error(this, i18n("Cannot create temporary file %1.").arg(m_backupName)); + return; + } + form->formFile()->setFileName(m_fileName); + if (!readOnlyFile || m_modified) + form->formFile()->setModified(true); + if (form->formFile()->save(false)) + { + if (!readOnlyFile && !KIO::NetAccess::file_copy(KURL::fromPathOrURL(m_fileName), KURL::fromPathOrURL(m_fileName + ".backup"), statbuf.st_mode, true)) + { + KMessageBox::error(this, i18n("Cannot create backup file %1.").arg(m_fileName + ".backup")); + } + ::chmod(m_fileName.local8Bit(), S_IRWXU); + KProcess* process = new KProcess; + process->setUseShell(true); + (*process) << "kommander" << QString("\"%1\"").arg(form->formFile()->fileName()); + connect(process, SIGNAL(receivedStdout(KProcess*, char*, int)), messageLog, + SLOT(receivedStdout(KProcess*, char*, int))); + connect(process, SIGNAL(receivedStderr(KProcess*, char*, int)), messageLog, + SLOT(receivedStderr(KProcess*, char*, int))); + connect(process, SIGNAL(processExited(KProcess*)), SLOT(closeRunningForm(KProcess*))); + messageLog->clear(MessageLog::All); + previewing = process->start(KProcess::NotifyOnExit, KProcess::AllOutput); + } +} + + void MainWindow::closeRunningForm(KProcess* process) { previewing = false; --- branches/KDE/3.5/kdewebdev/kommander/editor/mainwindow.h 2008/01/29 09:32:12 768069 +++ branches/KDE/3.5/kdewebdev/kommander/editor/mainwindow.h 2009/02/20 23:29:19 929242 @@ -191,6 +191,7 @@ void configureEditor(); void runForm(); + void runForm4(); private slots: void activeWindowChanged( QWidget *w ); --- branches/KDE/3.5/kdewebdev/kommander/editor/mainwindowactions.cpp 2008/01/29 09:32:12 768069 +++ branches/KDE/3.5/kdewebdev/kommander/editor/mainwindowactions.cpp 2009/02/20 23:29:19 929242 @@ -476,6 +476,14 @@ connect(this, SIGNAL(hasActiveForm(bool)), a, SLOT(setEnabled(bool))); a->plug(fileTb); a->plug(menu); + // add KDE4 executor + + KAction* b = new KAction(i18n("Run Dialog K4"), "launch", CTRL + SHIFT + Qt::Key_R, + this, SLOT(runForm4()), actionCollection(), "run4"); + b->setToolTip(i18n("Executes dialog in KDE4")); + b->setWhatsThis(whatsThisFrom("Run|Run dialog")); + connect(this, SIGNAL(hasActiveForm(bool)), b, SLOT(setEnabled(bool))); + b->plug(menu); } void MainWindow::setupWindowActions() --- branches/KDE/3.5/kdewebdev/quanta/project/projectupload.cpp 2007/01/08 16:02:33 621313 +++ branches/KDE/3.5/kdewebdev/quanta/project/projectupload.cpp 2009/02/19 13:42:47 928380 @@ -375,7 +375,7 @@ buttonUpload->setEnabled(false); KURL u = *baseUrl; u.setPath(u.protocol() == "file" ? "/" : ""); - if (QExtFileInfo::exists(u, false, this)) + if (QExtFileInfo::exists(u, false, this) || (u.protocol() == "webdav" && QExtFileInfo::exists(*baseUrl, false, this))) { upload(); return; --- branches/KDE/3.5/kdewebdev/lib/qextfileinfo.cpp 2008/01/26 16:48:39 766788 +++ branches/KDE/3.5/kdewebdev/lib/qextfileinfo.cpp 2009/02/19 13:42:47 928380 @@ -192,11 +192,11 @@ { int i = 0; bool result; - KURL dir3; + KURL dir3; KURL dir2; KURL dir1 = path; dir1.setPath("/"); - if (!exists(dir1, false, window)) + if (!exists(dir1, false, window) && path.protocol() != "webdav" ) { return false; //the root is not accessible, possible wrong username/password supplied } @@ -508,7 +508,7 @@ u.setPath(u.directory(false, true) + linkDest); u.cleanPath(); } - else + else u.setPath(linkDest); u.adjustPath(+1); if (!dirListItems.contains(u) && u.url() != m_listStartURL && !u.isParentOf(item->url())) --- branches/KDE/3.5/kdewebdev/kommander/plugin/specialinformation.cpp 2008/04/22 21:45:39 799932 +++ branches/KDE/3.5/kdewebdev/kommander/plugin/specialinformation.cpp 2009/11/02 20:05:06 1043999 @@ -379,6 +379,12 @@ i18n("Return the widget's geometry as x y w h. This is useful for positioning a created widget."), 1); insertInternal(DCOP::hasFocus, "hasFocus(QString widget)", i18n("Returns true if the widget has focus."), 1); + insertInternal(DCOP::getBackgroundColor, "getBackgroundColor(QString widget)", + i18n("Gets the widget's background color."), 1); + insertInternal(DCOP::setBackgroundColor, "setBackgroundColor(QString widget, QString Color)", + i18n("Sets the widget's background color. Colors can be by name, like blue, or in hex like #0000ff for blue. Use the color dialog or a color picker if unsure."), 2); + insertInternal(DCOP::isModified, "isModified(QString widget)", + i18n("See if widget has been modified."), 1); insertGroup(Group::Slots, i18n("Slots"), ""); @@ -442,7 +448,9 @@ i18n("Connects the signal of sender with the slot of the receiver"), 4); insertInternal(Kommander::disconnect, "disconnect(QString sender, QString signal, QString receiver, QString slot)", i18n("Disconnects the signal of sender from the slot of the receiver"), 4); - +/* insertInternal(Kommander::switchInternal, "switch(QString Variable)", + i18n("Can use can use
switch var
case 1
//code
else
//code
end

also can use the form of
switch var {
case 1; //code
else; code
}

semicolons are optional in place of returns. Currently switch does not parse value from arrays.") ); +*/ insertInternal(Kommander::exit, "exit", i18n("Exits script execution and returns"), 0); insertInternal(Kommander::Break, "break", @@ -480,7 +488,38 @@ i18n( "Remove keyNum elements starting with keyStart from an indexed array and reindex the array. If keyNum is not specified, remove only the keyStart element."), 2, 3); insertInternal(Array::indexedInsertElements, "indexedInsertElements(QString array, int key, QString string, QString separator)", i18n( "Insert the elements from string starting at key and reindex the array. Use the separator to separate the elements from the string. The separator's default value is '\\t'."), 3, 4); + insertInternal(Array::flipCopy, "flipCopy(QString Array, QString Copy)", + i18n("Create a flipped copy of the array where the keys and values switch places. NOTE: If the values are not unique they will be overwritten as keys! Set the name of the array to copy to and go. Useful with combos and lists were you have an index, a key and a value for data purposes."), 2, 2); + insertGroup(Group::Matrix, "Matrix", "matrix"); + insertInternal(Matrix::fromString, "fromString(QString matrix, QString String, bool With-Row-Keys, bool With-Col-Keys)", + i18n("Create a 2D array with zero based integer keys. Rows seperated with returns or \\n and columns with tabs or \\t. You can then read and alter values with \"name[0][1]\".
NOTE: Watch keys! The row and column keys when set to true will read respectively the first row and first column as headings. If for instance you set one where there is no column or row heading to read it will read data, and if the data is not unique you will have missing columns or rows as well as addressing not working."), 2, 4); + insertInternal(Matrix::toString, "toString(QString matrix, bool RowHeadings, bool ColHeadings)", + i18n("Convert 2D array to string, optionaly with row and column headings. If written without values set it will default to no headings."), 1, 3); + insertInternal(Matrix::rows, "rows(QString matrix)", + i18n("Return the number of rows in the matrix"), 1); + insertInternal(Matrix::columns, "columns(QString matrix)", + i18n("Return the number of columns in the matrix"), 1); + insertInternal(Matrix::clear, "clear(QString matrix)", + i18n("Clear the entire matrix"), 1); + insertInternal(Matrix::rowToArray, "rowToArray(QString matrix, QString Row, QString Array, bool Clear-First, bool Indexed)", + i18n("Convert row to array. Useful break out rows of data to work with. If you want to avoid spurious data Clear-First will wipe the array before filling it. If you choose indexed it will use a zero based index. Otherwise it will use the column keys."), 3, 5); + insertInternal(Matrix::columnToArray, "columnToArray(QString matrix, QString Column, QString Array)", + i18n("Copy a column of a Matrix to an array and optionally clear array first to avoid spurious data in loops"), 3); + insertInternal(Matrix::columnToIndexedArray, "columnToIndexedArray(QString matrix, QString Column, QString Array)", + i18n("Copy a column of a Matrix to an indexed array"), 3); + insertInternal(Matrix::rowKeys, "rowKeys(QString Matrix, QString Seperator)", + i18n("Return the row keys from the matrix. Separator defaults to [tab] \"\\t\" if left empty"), 1, 2); + insertInternal(Matrix::columnKeys, "columnKeys(QString Matrix, QString Seperator)", + i18n("Return the column keys from the matrix. Separator defaults to [tab] \"\\t\" if left empty"), 1, 2); + insertInternal(Matrix::addRow, "addRow(QString Matrix, QString RowKey, QString data)", + i18n("Add a row to the matrix. Specifiy the row key and format the data as column key [tab] column value on each line using key\\tval\\nkey\\tval format"), 3); + insertInternal(Matrix::removeRow, "removeRow(QString Matrix, QString RowKey)", + i18n("Remove a row from the matrix by key name. Returns true if key is found."), 2); + insertInternal(Matrix::removeColumn, "removeColumn(QString Matrix, QString ColKey)", + i18n("Remove a column from the matrix by key name. Returns true if key is found."), 2); + insertInternal(Matrix::findRow, "findRow(QString Matrix, QString Col-Key, QString Col-Value, int Iteration)", + i18n("Find the row key that matches a column value. Use this for unique key searches. Iteration may be omitted and the default is to return the first instance. In a loop it will return sequential finds until there are no more, in which case it returns null."), 3, 4); insertGroup(Group::String, "String", "str"); insert(String::length, "length(QString string)", @@ -490,7 +529,9 @@ insert(String::find, "find(QString string, QString sought, int index)", i18n("Returns the position of a substring in the string, or -1 if it is not found."), 2); insert(String::findRev, "findRev(QString string, QString sought, int index)", - i18n("Returns the position of a substring in the string, or -1 if it is not found. String is searched backwards"), 2); + i18n("Returns the position of a substring in the string, or -1 if it is not found. String is searched backwards"), 2); + insertInternal(String::count, "count(QString String, QString substring)", + i18n("Returns the count of a given substring in the given string."), 2); insert(String::left, "left(QString string, int n)", i18n("Returns the first n chars of the string."), 2); insert(String::right, "right(QString string, int n)", @@ -518,6 +559,14 @@ i18n("Returns the given string with %1, %2, %3 replaced with arg1, arg2, arg3 accordingly."), 2); insert(String::round, "round(QString Number, int Digits)", i18n("Round a floating point number by x digits."), 2); + insertInternal(String::sort, "sort(QString String, QString Separator)", + i18n("Sort a string list. Only first paramter is required. Default separator is a newline."), 1, 2); + insertInternal(String::trim, "trim(QString String)", + i18n("Strips white space from beginning and end of string."), 1); + insertInternal(String::padLeft, "padLeft(QString String, int Length, QString Pad)", + i18n("Pads the string to the total length indicated. if no pad character is given spaces will be used. Try this with 0 on integer sequences and read them with str_toint."), 1, 2); + insertInternal(String::padRight, "padRight(QString String, int Length, QString Pad)", + i18n("Pads the string to the total length indicated. if no pad character is given spaces will be used."), 1, 2); insertInternal(String::toInt, "toint(QString string, QString default)", i18n("Convert a string to an integer. If not possible use the default value"), 1, 2); @@ -543,7 +592,7 @@ insert(Input::value, "value(QString caption, QString label, int value, int min, int max, int step)", i18n("Shows value selection dialog. Returns entered value."), 5); insert(Input::valueDouble, "double(QString caption, QString label, double value, double min, double max, double step)", - i18n("Shows float value selection dialog. Returns entered value."), 5); + i18n("Shows float value selection dialog. Returns entered value."), 6); insert(Input::openfile, "openfile(QString startdir, QString filter, QString caption)", i18n("Shows existing file selection dialog. Returns selected file."), 0); insert(Input::savefile, "savefile(QString startdir, QString filter, QString caption)", @@ -555,9 +604,9 @@ insertGroup(Group::Message, "Message", "message"); insert(Message::info, "info(QString text, QString caption)", - i18n("Shows an information dialog."), 1); + i18n("Shows an information dialog. Returns true when clicked so you can check for user response."), 1); insert(Message::error, "error(QString text, QString caption)", - i18n("Shows an error dialog."), 1); + i18n("Shows an error dialog. Returns true when clicked so you can check for user response."), 1); insert(Message::warning, "warning(QString text, QString caption, QString button1, QString button2, QString button3)", i18n("Shows a warning dialog with up to three buttons. Returns number of selected button."), 1); insert(Message::question, "question(QString text, QString caption, QString button1, QString button2, QString button3)", --- branches/KDE/3.5/kdewebdev/kommander/plugin/specials.h 2008/04/18 22:38:16 798709 +++ branches/KDE/3.5/kdewebdev/kommander/plugin/specials.h 2009/10/14 15:34:33 1035239 @@ -23,7 +23,7 @@ namespace Group { - enum {DCOP, Kommander, String, Array, File, Input, Message, Slots}; + enum {DCOP, Kommander, String, Array, File, Input, Message, Slots, Matrix}; } namespace DCOP @@ -32,26 +32,31 @@ currentItem, currentRow, execute, findItem, global, insertColumn, insertItem, insertItems, insertRow, item, itemDepth, itemPath, removeColumn, removeItem, removeRow, selection, setAssociatedText, setChecked, setCellText, setCurrentItem, insertTab, setColumnCaption, setEnabled, setGlobal, setMaximum, setPixmap, - setRowCaption, setSelection, setText, - setVisible, text, type, setCellWidget, cellWidget, setEditable, geometry, hasFocus}; + setRowCaption, setSelection, setText, getBackgroundColor, setBackgroundColor, + setVisible, text, type, setCellWidget, cellWidget, setEditable, geometry, hasFocus, isModified}; } namespace Kommander { enum {widgetText, selectedWidgetText, null, pid, dcopid, parentPid, debug, echo, env, exec, expr, global, i18n, dialog, readSetting, setGlobal, writeSetting, dcop, - switchBlock, execBegin, forBlock, forEachBlock, ifBlock, comment, createWidget, connect, disconnect, widgetExists, exit, Break, Continue, Return, execBackground}; + switchBlock, execBegin, forBlock, forEachBlock, ifBlock, comment, createWidget, connect, disconnect, widgetExists, exit, Break, Continue, Return, execBackground, switchInternal}; //, focusWidget}; } namespace Array { - enum {values, keys, clear, count, value, remove, setValue, fromString, toString, indexedFromString, indexedToString, indexedRemoveElements, indexedInsertElements}; + enum {values, keys, clear, count, value, remove, setValue, fromString, toString, indexedFromString, indexedToString, indexedRemoveElements, indexedInsertElements, flipCopy}; +} + +namespace Matrix +{ + enum {fromString, toString, clear, rows, columns, rowToArray, columnToArray, columnToIndexedArray, rowKeys, columnKeys, addRow, removeRow, removeColumn, findRow}; } namespace String { enum {length, contains, find, findRev, left, right, mid, remove, replace, upper, lower, - compare, isEmpty, isNumber, section, args, toInt, toDouble, round}; + compare, isEmpty, isNumber, section, args, toInt, toDouble, round, sort, trim, padLeft, padRight, count}; } namespace File --- branches/KDE/3.5/kdewebdev/kommander/factory/kommanderversion.h 2008/01/16 15:30:59 762237 +++ branches/KDE/3.5/kdewebdev/kommander/factory/kommanderversion.h 2009/11/02 20:05:06 1043999 @@ -1,7 +1,7 @@ #ifndef __VERSION_H__ #define __VERSION_H__ -#define KOMMANDER_VERSION "1.3" +#define KOMMANDER_VERSION "1.5.3" #endif --- branches/KDE/3.5/kdewebdev/kommander/widget/parsenode.cpp 2007/09/29 20:55:44 718841 +++ branches/KDE/3.5/kdewebdev/kommander/widget/parsenode.cpp 2009/10/07 22:02:40 1032474 @@ -120,11 +120,21 @@ return type() == ValueKeyword && keyword() == Variable; } +bool ParseNode::isArray() const +{ + return type() == ValueKeyword && keyword() == Array; +} + QString ParseNode::variableName() const { return isVariable() ? m_string : QString(); } +QString ParseNode::arrayName() const +{ + return isArray() ? m_string : QString(); +} + QString ParseNode::errorMessage() const { return isValid() ? QString() : m_string; @@ -228,6 +238,13 @@ m_string = name; } +void ParseNode::setArray(const QString& name) +{ + m_type = ValueKeyword; + m_keyword = Array; + m_string = name; +} + bool ParseNode::isValue() const { return m_type <= ValueValue; --- branches/KDE/3.5/kdewebdev/kommander/widget/parser.h 2008/01/28 19:58:35 767795 +++ branches/KDE/3.5/kdewebdev/kommander/widget/parser.h 2009/10/11 19:41:56 1034032 @@ -68,6 +68,16 @@ void unsetArray(const QString& name, const QString& key = QString::null); // array value ParseNode arrayValue(const QString& name, const QString& key) const; + // access 2D array + const QMap >& matrix(const QString& name) const; + // check if this is name of a 2D array + bool isMatrix(const QString& name) const; + // set array key + void setMatrix(const QString& name, const QString& keyr, const QString& keyc, ParseNode value); + // unset array key or whole array + void unsetMatrix(const QString& name, const QString& keyr = QString::null, const QString& keyc = QString::null); + // array value + ParseNode matrixValue(const QString& name, const QString& keyr, const QString& keyc) const; // get associated widget KommanderWidget* currentWidget() const; @@ -133,6 +143,8 @@ void insertNode(ParseNode p, int line); // next item to be parsed ParseNode next() const; + // next is Else or Else && If? + bool nextElseIf(); // check if next item is keyword k, if so - go further, if no, set error bool tryKeyword(Parse::Keyword k, Parse::Mode mode = Parse::Execute); // check if next item is a variable, if so, return its name @@ -169,12 +181,16 @@ QMap m_variables; // arrays QMap > m_arrays; + // 2D arrays + QMap > > m_matrices; // Kommander KommanderWidget* m_widget; // global variables static QMap m_globalVariables; // global arrays static QMap > m_globalArrays; + // global 2D arrays + static QMap > > m_globalMatrices; }; #endif --- branches/KDE/3.5/kdewebdev/kommander/widget/parserdata.cpp 2007/09/29 20:55:44 718841 +++ branches/KDE/3.5/kdewebdev/kommander/widget/parserdata.cpp 2009/10/15 07:34:24 1035469 @@ -59,6 +59,8 @@ m_keywords["else"] = Else; m_keywords["elseif"] = Elseif; m_keywords["endif"] = Endif; + m_keywords["{"] = LeftCurlyBrace; + m_keywords["}"] = RightCurlyBrace; m_keywords["switch"] = Switch; m_keywords["case"] = Case; m_keywords["while"] = While; @@ -90,13 +92,19 @@ m_keywords["("] = LeftParenthesis; m_keywords[")"] = RightParenthesis; m_keywords["["] = LeftBracket; + m_keywords["]["] = DoubleBracket; m_keywords["]"] = RightBracket; m_keywords["+"] = Plus; m_keywords["-"] = Minus; m_keywords["*"] = Multiply; m_keywords["/"] = Divide; m_keywords["%"] = Mod; + m_keywords["+="] = PlusEqual; + m_keywords["-="] = MinusEqual; + m_keywords["++"] = Increment; + m_keywords["--"] = Decrement; m_keywords["mod"] = Mod; + m_keywords["with"] = ArrKeyVal; m_groups[Less] = GroupComparison; m_groups[LessEqual] = GroupComparison; --- branches/KDE/3.5/kdewebdev/kommander/widget/parsenode.h 2008/01/16 19:29:11 762302 +++ branches/KDE/3.5/kdewebdev/kommander/widget/parsenode.h 2009/10/15 07:34:24 1035469 @@ -23,8 +23,8 @@ { enum Keyword {For, To, Step, End, While, Do, Foreach, In, If, Then, Else, Elseif, Endif, Switch, Case, Break, Continue, Exit, Dot, Semicolon, Comma, Assign, Less, LessEqual, Greater, GreaterEqual, Equal, NotEqual, - Not, And, Or, False, True, LeftParenthesis, RightParenthesis, LeftBracket, RightBracket, - Plus, Minus, Multiply, Divide, Mod, LastRealKeyword = Mod, Variable, Invalid}; + Not, And, Or, False, True, LeftParenthesis, RightParenthesis, LeftBracket, DoubleBracket, RightBracket, LeftCurlyBrace, RightCurlyBrace, PlusEqual, MinusEqual, Increment, Decrement, + Plus, Minus, Multiply, Divide, Mod, LastRealKeyword = Mod, Variable, Invalid, Array, Matrix, ArrKeyVal}; enum KeywordGroup {GroupComparison, GroupAdd, GroupMultiply, GroupMisc}; enum ValueType {ValueString, ValueInt, ValueDouble, ValueValue = ValueDouble, ValueKeyword, @@ -74,8 +74,12 @@ bool isKeyword(Parse::Keyword k) const; /* Check if current value is a variable */ bool isVariable() const; + /* Check if current value is an Array */ + bool isArray() const; /* Return the name of variable */ QString variableName() const; + /* Return the name of array */ + QString arrayName() const; /* Return error message if applicable */ QString errorMessage() const; /* Calculate common type for two nodes */ @@ -100,6 +104,8 @@ void setValue(const QString& s); /* set value as variable */ void setVariable(const QString& name); + /* set value as array */ + void setArray(const QString& name); /* check if it is correct value */ bool isValue() const; /* for setting some context information, f. e. for bug reporting */ --- branches/KDE/3.5/kdewebdev/kommander/widget/parser.cpp 2008/02/02 08:05:04 769847 +++ branches/KDE/3.5/kdewebdev/kommander/widget/parser.cpp 2009/10/15 17:48:00 1035715 @@ -99,6 +99,15 @@ { while (start < s.length() && s[start] != '\n') start++; + } // enable /* */ block comments + else if (s[start] == '/' && start < s.length() +1 && s[start+1] == '*') + { + start += 2; + while (start < s.length() +1 && !(s[start] == '*' && s[start+1] == '/')) + { + start++; + } + start += 2; } // special keyword: <> else if (m_data->stringToKeyword(s.mid(start, 2)) <= LastRealKeyword) { @@ -194,10 +203,12 @@ } return p; } - +//attempting to allow assign or copy of array, so far with no joy ParseNode Parser::parseValue(Mode mode) { ParseNode p = next(); + //QString p2 = QString(p.toString()); + //qDebug("parseValue p2 = "+p2); if (isFunction()) return parseFunction(mode); else if (isWidget()) @@ -207,6 +218,13 @@ if (tryKeyword(LeftBracket, CheckOnly)) { QString index = parseValue(mode).toString(); + if (tryKeyword(DoubleBracket, CheckOnly)) + {//2D array "matrix" + QString index2 = parseValue(mode).toString(); + tryKeyword(RightBracket); + QString arr = p.variableName(); + return matrixValue(arr, index, index2); + } tryKeyword(RightBracket); QString arr = p.variableName(); return arrayValue(arr, index); @@ -242,6 +260,11 @@ return ParseNode(0); else if (tryKeyword(True, CheckOnly)) return ParseNode(1); +/* else if (isArray(p2)) + { + qDebug("returning array fpr p2"); + return p2; + }*/ else if (p.isKeyword()) setError(i18n("Expected value")); else // single value @@ -411,6 +434,7 @@ { int pos = m_start; QString name = next().variableName(); + //qDebug("Parsing function: "+name); Function f = m_data->function(name); m_start++; ParameterList params; @@ -484,20 +508,188 @@ ParseNode Parser::parseAssignment(Mode mode) { QString var = nextVariable(); + //qDebug("var = "+var+" Pos:"+QString::number(m_start)); if (tryKeyword(LeftBracket, CheckOnly)) { QString index = parseValue(mode).toString(); - tryKeyword(RightBracket); - tryKeyword(Assign); + if (tryKeyword(DoubleBracket, CheckOnly)) + {//2D array "matrix" + ParseNode p1 = next(); //move along... + QString index2 = parseValue(mode).toString(); + tryKeyword(RightBracket); + p1 = next(); + ParseNode p2 = matrixValue(var, index, index2); + if (p1.isKeyword(PlusEqual)) + { + tryKeyword(PlusEqual); + ParseNode p = parseExpression(mode); + if (mode == Execute) + { + if (p2.type() == ValueString) + p = QString(p2.toString() + p.toString()); + else if (p2.type() == ValueDouble) + p = p2.toDouble() + p.toDouble(); + else + p = p2.toInt() + p.toInt(); + setMatrix(var, index, index2, p); + } + } + else if (p1.isKeyword(MinusEqual)) + { + tryKeyword(MinusEqual); + ParseNode p = parseExpression(mode); + if (mode == Execute) + { + if (p2.type() == ValueDouble) + p = p2.toDouble() - p.toDouble(); + else + p = p2.toInt() - p.toInt(); + setMatrix(var, index, index2, p); + } + } + else if (p1.isKeyword(Increment)) + { + tryKeyword(Increment); + if (mode == Execute) + { + p2 = p2.toInt() + 1; + setMatrix(var, index, index2, p2); + } + } + else if (p1.isKeyword(Decrement)) + { + tryKeyword(Decrement); + if (mode == Execute) + { + p2 = p2.toInt() - 1; + setMatrix(var, index, index2, p2); + } + } + else + { + tryKeyword(Assign); + ParseNode p = parseExpression(mode); + if (mode == Execute) + setMatrix(var, index, index2, p); + } + } + else + { + tryKeyword(RightBracket); + ParseNode p1 = next(); + // seems awkward and pedantic but array values are now handled like variables + // for special assign with oparator + ParseNode p2 = arrayValue(var, index); + if (p1.isKeyword(PlusEqual)) + { + tryKeyword(PlusEqual); + ParseNode p = parseExpression(mode); + if (mode == Execute) + { + if (p2.type() == ValueString) + p = QString(p2.toString() + p.toString()); + else if (p2.type() == ValueDouble) + p = p2.toDouble() + p.toDouble(); + else + p = p2.toInt() + p.toInt(); + setArray(var, index, p); + } + } + else if (p1.isKeyword(MinusEqual)) + { + tryKeyword(MinusEqual); + ParseNode p = parseExpression(mode); + if (mode == Execute) + { + if (p2.type() == ValueDouble) + p = p2.toDouble() - p.toDouble(); + else + p = p2.toInt() - p.toInt(); + setArray(var, index, p); + } + } + else if (p1.isKeyword(Increment)) + { + tryKeyword(Increment); + if (mode == Execute) + { + p2 = p2.toInt() + 1; + setArray(var, index, p2); + } + } + else if (p1.isKeyword(Decrement)) + { + tryKeyword(Decrement); + if (mode == Execute) + { + p2 = p2.toInt() - 1; + setArray(var, index, p2); + } + } + else + { + tryKeyword(Assign); + ParseNode p = parseExpression(mode); + if (mode == Execute) + setArray(var, index, p); + } + } + } + else if (tryKeyword(Assign, CheckOnly)) + { ParseNode p = parseExpression(mode); if (mode == Execute) - setArray(var, index, p); + { + setVariable(var, p); + } } - else if (tryKeyword(Assign, CheckOnly)) + else if (tryKeyword(PlusEqual, CheckOnly)) { ParseNode p = parseExpression(mode); if (mode == Execute) + { + ParseNode p2 = variable(var); + if (p2.type() == ValueString) + p = QString(p2.toString() + p.toString()); + else if (p2.type() == ValueDouble) + p = p2.toDouble() + p.toDouble(); + else + p = p2.toInt() + p.toInt(); setVariable(var, p); + } + } + else if (tryKeyword(MinusEqual, CheckOnly)) + { + ParseNode p = parseExpression(mode); + if (mode == Execute) + { + ParseNode p2 = variable(var); + if (p2.type() == ValueDouble) + p = p2.toDouble() - p.toDouble(); + else + p = p2.toInt() - p.toInt(); + setVariable(var, p); + } + } + else if (tryKeyword(Increment, CheckOnly)) + { + //ParseNode p = parseExpression(mode); + if (mode == Execute) + { + ParseNode p = variable(var); + p = p.toInt() + 1; + setVariable(var, p); + } + } + else if (tryKeyword(Decrement, CheckOnly)) + { + //ParseNode p = parseExpression(mode); + if (mode == Execute) + { + ParseNode p = variable(var); + p = p.toInt() - 1; + setVariable(var, p); + } } else if (tryKeyword(Dot, CheckOnly)) { @@ -529,11 +721,14 @@ ParseNode p = next(); Flow flow = FlowStandard; bool matched = false; + bool thenFound = false; do { m_start++; Mode m = matched ? CheckOnly : mode; p = parseCondition(m); - tryKeyword(Then); + thenFound = tryKeyword(Then, CheckOnly); + if (!thenFound) + tryKeyword(LeftCurlyBrace); bool condition = !matched && p.toBool(); if (condition) { @@ -544,29 +739,52 @@ else parseBlock(CheckOnly); matched = matched || p.toBool(); - } while (next().isKeyword(Elseif)); + if (!thenFound) + tryKeyword(RightCurlyBrace); + } while (nextElseIf() == true); + bool braceFound = false; if (tryKeyword(Else, CheckOnly)) { + braceFound = tryKeyword(LeftCurlyBrace, CheckOnly); if (!matched) flow = parseBlock(mode); else parseBlock(CheckOnly); } + if (braceFound) + tryKeyword(RightCurlyBrace); + if (thenFound) tryKeyword(Endif); return flow; } +bool Parser::nextElseIf() +{ + ParseNode p1 = next(); + if (p1.isKeyword(Elseif)) + return true; + else + { + ParseNode p2 = next(); + if (p1.isKeyword(Else) && p2.isKeyword(If) ) + return true; + } + return false; +} + Parse::Flow Parser::parseWhile(Mode mode) { m_start++; int start = m_start; bool running = true; Parse::Flow flow = FlowStandard; + bool doFound = false; while (running) { m_start = start; ParseNode p = parseCondition(mode); - if (!tryKeyword(Do)) + doFound = tryKeyword(Do, CheckOnly); + if (!doFound && !tryKeyword(LeftCurlyBrace)) break; running = p.toBool(); flow = parseBlock(running ? mode : CheckOnly); @@ -575,7 +793,10 @@ } if (flow != FlowExit) { - tryKeyword(End); + if (doFound) + tryKeyword(End); + else + tryKeyword(RightCurlyBrace); return FlowStandard; } else @@ -593,10 +814,13 @@ int step = 1; if (tryKeyword(Step, CheckOnly)) step = parseExpression(mode).toInt(); - tryKeyword(Do); + + bool doFound = tryKeyword(Do, CheckOnly); + if (!doFound) + tryKeyword(LeftCurlyBrace); int block = m_start; Parse::Flow flow = FlowStandard; - if (end >= start) + if (end >= start && step > 0) { for (int i = start; i <= end; i+=step) { @@ -606,11 +830,24 @@ if (flow == FlowBreak || flow == FlowExit) break; } + } else if (end <= start && step < 0) + { + for (int i = start; i >= end; i+=step) + { + m_start = block; + setVariable(var, ParseNode(i)); + flow = parseBlock(mode); + if (flow == FlowBreak || flow == FlowExit) + break; + } } else parseBlock(Parse::CheckOnly); if (flow != FlowExit) { - tryKeyword(End); + if (doFound) + tryKeyword(End); + else + tryKeyword(RightCurlyBrace); return FlowStandard; } else @@ -621,12 +858,22 @@ { m_start++; QString var = nextVariable(); + QString var2 = ""; + bool matrixfound = tryKeyword(ArrKeyVal, CheckOnly); + if (matrixfound == true) + { + m_start--; + tryKeyword(ArrKeyVal); + var2 = nextVariable(); + } tryKeyword(In); QString arr = nextVariable(); - tryKeyword(Do); + bool doFound = tryKeyword(Do, CheckOnly); + if (!doFound) + tryKeyword(LeftCurlyBrace); int start = m_start; Parse::Flow flow = FlowStandard; - if (isArray(arr) && array(arr).count()) + if (isArray(arr) && array(arr).count() && !matrixfound) { const QMap A = array(arr); for (QMapConstIterator It = A.begin(); It != A.end(); ++It) @@ -638,11 +885,41 @@ break; } } + else if (isMatrix(arr) && matrix(arr).count() ) + { + const QMap > A = matrix(arr); + for (QMapConstIterator > It = A.begin(); It != A.end(); ++It) + { + m_start = start; + setVariable(var, It.key()); + if (matrixfound == true) + { + const QMap B = It.data(); + for (QMapConstIterator It2 = B.begin(); It2 != B.end(); ++It2 ) + { + m_start = start; + setVariable(var2, It2.key()); + flow = parseBlock(mode); + if (flow == FlowBreak || flow == FlowExit) + break; + } + } + else + { + flow = parseBlock(mode); + if (flow == FlowBreak || flow == FlowExit) + break; + } + } + } else parseBlock(CheckOnly); if (flow != FlowExit) { - tryKeyword(End); + if (doFound) + tryKeyword(End); + else + tryKeyword(RightCurlyBrace); return FlowStandard; } else @@ -655,6 +932,8 @@ QString var = nextVariable(); ParseNode caseValue = variable(var); bool executed = false; + bool braceFound = false; + braceFound = tryKeyword(LeftCurlyBrace, CheckOnly); tryKeyword(Semicolon, CheckOnly); while (tryKeyword(Case, CheckOnly)) { @@ -666,12 +945,17 @@ } if (tryKeyword(Else, CheckOnly)) parseBlock(executed ? CheckOnly : mode); - tryKeyword(End); + if (!braceFound) + tryKeyword(End); + else + tryKeyword(RightCurlyBrace); } Flow Parser::parseCommand(Mode mode) { ParseNode p = next(); + QString p2 = p.toString(); + //qDebug("Parsing command: "+p2); if (next().isKeyword(If)) return parseIf(mode); else if (next().isKeyword(While)) @@ -740,7 +1024,7 @@ if (k == Dot) setError(i18n("Expected '%1'

Possible cause of the error is having a variable with the same name as a widget").arg(m_data->keywordToString(k))); else - setError(i18n("Expected '%1'").arg(m_data->keywordToString(k))); + setError(i18n("Expected '%1' got '%2'.").arg(m_data->keywordToString(k)).arg(next().toString())); } return false; } @@ -886,6 +1170,66 @@ return m_arrays[name].contains(key) ? m_arrays[name][key] : ParseNode(); } +// 2D arrays "Matrix" +const QMap >& Parser::matrix(const QString& name) const +{ + if (isGlobal(name)) + return m_globalMatrices[name]; + else + return m_matrices[name]; +} + +bool Parser::isMatrix(const QString& name) const +{ + return m_matrices.contains(name) || m_globalMatrices.contains(name); +} + +void Parser::setMatrix(const QString& name, const QString& keyr, const QString& keyc, ParseNode value) +{ + if (isGlobal(name)) + m_globalMatrices[name][keyr][keyc] = value; + else + m_matrices[name][keyr][keyc] = value; +} + +void Parser::unsetMatrix(const QString& name, const QString& keyr, const QString& keyc) +{ + if (isGlobal(name)) + { + if (keyr.isNull()) + m_globalMatrices.remove(name); + else if (isMatrix(name)) + { + if (keyc.isNull()) + m_globalMatrices[name].remove(keyr); + else + m_globalMatrices[name][keyr].remove(keyc); + } + } + else + { + if (keyr.isNull()) + m_matrices.remove(name); + else if (isMatrix(name)) + { + if (keyc.isNull()) + m_matrices[name].remove(keyr); + else + m_matrices[name][keyr].remove(keyc); + } + } +} + +ParseNode Parser::matrixValue(const QString& name, const QString& keyr, const QString& keyc) const +{ + if (!isMatrix(name)) + return ParseNode(); + if (isGlobal(name)) + return m_globalMatrices[name].contains(keyr) && m_globalMatrices[name][keyr].contains(keyc) ? m_globalMatrices[name][keyr][keyc] : ParseNode(); + else + return m_matrices[name].contains(keyr) && m_matrices[name][keyr].contains(keyc) ? m_matrices[name][keyr][keyc] : ParseNode(); +} + KommanderWidget* Parser::currentWidget() const @@ -895,5 +1239,5 @@ QMap Parser::m_globalVariables; QMap > Parser::m_globalArrays; - +QMap > > Parser::m_globalMatrices; --- branches/KDE/3.5/kdewebdev/kommander/widget/functionlib.cpp 2008/04/18 01:46:04 798347 +++ branches/KDE/3.5/kdewebdev/kommander/widget/functionlib.cpp 2009/12/21 06:08:36 1064505 @@ -80,6 +80,18 @@ params.count() == 3 ? params[2].toInt() : params[0].toString().length()); } +static ParseNode f_stringCount(Parser*, const ParameterList& params) +{ + int c = 0; + int s = 0; + while (params[0].toString().find(params[1].toString(), s) > -1) + { + s = params[0].toString().find(params[1].toString(), s) + 1; + c++; + } + return c; +} + static ParseNode f_stringLeft(Parser*, const ParameterList& params) { return params[0].toString().left(params[1].toInt()); @@ -120,6 +132,44 @@ return params[0].toString().isEmpty(); } +static ParseNode f_stringSort(Parser*, const ParameterList& params) +{ + if (params.count() == 2 ) + { + QStringList tmplst = QStringList::split(params[1].toString(), params[0].toString()); + tmplst.sort(); + return tmplst.join(params[1].toString()); + } + else + { + QStringList tmplst = QStringList::split("\n", params[0].toString()); + tmplst.sort(); + return tmplst.join("\n"); + } +} +static ParseNode f_stringTrim(Parser*, const ParameterList& params) +{ + return params[0].toString().stripWhiteSpace(); +} + +static ParseNode f_stringPadLeft(Parser*, const ParameterList& params) +{ + if (params.count() == 2 ) + return params[0].toString().rightJustify(params[1].toInt(), ' ', false); + QString s = params[2].toString(); + QChar ch = s.at(0); + return params[0].toString().rightJustify(params[1].toInt(), ch, false); +} + +static ParseNode f_stringPadRight(Parser*, const ParameterList& params) +{ + if (params.count() == 2 ) + return params[0].toString().leftJustify(params[1].toInt(), ' ', false); + QString s = params[2].toString(); + QChar ch = s.at(0); + return params[0].toString().leftJustify(params[1].toInt(), ch, false); +} + static ParseNode f_stringSection(Parser*, const ParameterList& params) { return params[0].toString().section(params[1].toString(), params[2].toInt(), @@ -553,7 +603,7 @@ static ParseNode f_arrayRemove(Parser* P, const ParameterList& params) { - if (!P->isArray(params[0].toString())) + if (P->isArray(params[0].toString())) P->unsetArray(params[0].toString(), params[1].toString()); return ParseNode(); } @@ -697,6 +747,429 @@ return ParseNode(); } +static ParseNode f_arrayFlipCopy(Parser* P, const ParameterList& params) +{ + QString name = params[0].toString(); + if (!P->isArray(name)) + return ParseNode(); + QString arr = params[1].toString(); + const QMap A = P->array(name); + for (QMapConstIterator It = A.begin(); It != A.end(); ++It ) + { + P->setArray(arr, (*It).toString(), It.key() ); + } + return ParseNode(); +} + +/*********** matrix (2D array) functions ********/ +static ParseNode f_matrixClear(Parser* P, const ParameterList& params) +{ + P->unsetMatrix(params[0].toString()); + return ParseNode(); +} + +static ParseNode f_matrixToString(Parser* P, const ParameterList& params) +{ + QString name = params[0].toString(); + if (!P->isMatrix(name)) + return ParseNode(); + QString matrix; + QString colhead; + const QMap > A = P->matrix(name); + int r = 0; + int c = 0; + int frow = 0; + int fcol = 0; + if (params.count() >= 1) + frow = params[1].toInt(); //row headings + if (params.count() >= 2) + fcol = params[2].toInt(); //col headings + QString tmp; + typedef QMap col_map; + col_map col_head; + for (QMapConstIterator > It1 = A.begin(); It1 != A.end(); ++It1 ) + { + const QMap B = It1.data(); + for (QMapConstIterator It2 = B.begin(); It2 != B.end(); ++It2 ) + { + bool colfound = false; + for (QMapConstIterator It3 = col_head.begin(); It3 != col_head.end(); ++It3 ) + { + if (It2.key() == (*It3)) + { + colfound = true; + break; + } + } + if (!colfound) + { + col_head[c] = It2.key(); + if (c > 0) + colhead.append("\t"); + colhead.append(It2.key()); + c++; + } + } + } + if (fcol && frow) + colhead.prepend("\t"); + for (QMapConstIterator > It1 = A.begin(); It1 != A.end(); ++It1) + { + if (r > 0 ) + matrix.append("\n"); + if (frow) //add row keys + { + tmp = It1.key(); + matrix.append(tmp+"\t"); + } + c = 0; + const QMap B = col_head; + for (QMapConstIterator It2 = B.begin(); It2 != B.end(); ++It2 ) + { + if (c > 0) + matrix.append("\t"); + matrix.append(P->matrixValue(name, It1.key(), (*It2) ).toString()); + c++; + } + r++; + } + if (fcol) + matrix.prepend(colhead+"\n"); + return matrix; +} + +static ParseNode f_matrixFromString(Parser* P, const ParameterList& params) +{ + QString name = params[0].toString(); + QStringList rows = QStringList::split("\n", params[1].toString()); + int r = 0; + int frow = 0; + int fcol = 0; + QString rkey; + QMap colhead; + if (params.count() > 1) + frow = params[2].toInt(); //row headings + if (params.count() > 2) + fcol = params[3].toInt(); //col headings + for (QStringList::Iterator itr = rows.begin(); itr != rows.end(); ++itr ) + { + int c = 0; + QString ckey; + QStringList cols = QStringList::split("\t", (*itr), true); + for (QStringList::Iterator itc = cols.begin(); itc != cols.end(); ++itc ) + { + QString val = (*itc).stripWhiteSpace(); + if (frow) + { + if (c == 0 && !val.isEmpty()) + { + rkey = val; + } + } + else if (fcol) + rkey = QString::number(r-1); + else + rkey = QString::number(r); + if (fcol && r == 0 && c >= 0) + { + if (!val.isEmpty()) + colhead[c] = val; + else + colhead[c] = QString::number(c); + } + if (!val.isEmpty() && !(c == 0 && frow) && !(r == 0 && fcol)) + { + if (fcol) + ckey = colhead[c]; + else + ckey = QString::number(c); + P->setMatrix(name, rkey, ckey, val); + } + c++; + } + r++; + } + return ParseNode(); +} + +static ParseNode f_matrixRows(Parser* P, const ParameterList& params) +{ + if (P->isMatrix(params[0].toString())) + return (uint)(P->matrix(params[0].toString()).count()); + else + return (uint)0; + +} + +static ParseNode f_matrixRowKeys(Parser* P, const ParameterList& params) +{ + QString name = params[0].toString(); + if (!P->isMatrix(name)) + return ParseNode(); + QString matrix; + QString tmp; + QString separator = "\t"; + if (params.count() == 2) + separator = params[1].toString(); + const QMap > A = P->matrix(name); + int r = 0; + for (QMapConstIterator > It1 = A.begin(); It1 != A.end(); ++It1) + { + if (r > 0 ) + matrix.append(separator); + tmp = It1.key(); + matrix.append(tmp); + r++; + } + return matrix; +} + +static ParseNode f_matrixFindRow(Parser* P, const ParameterList& params) +{ + QString name = params[0].toString(); + if (!P->isMatrix(name)) + return ParseNode(); + QString col = params[1].toString(); + QString val = params[2].toString(); + QString tmp; + int i = 0; + int find; + if (params.count() == 4) + find = params[3].toInt(); + else + find = 0; + const QMap > A = P->matrix(name); + for (QMapConstIterator > It = A.begin(); It != A.end(); ++It) + { + if (val == P->matrixValue(name, It.key(), col).toString()) + { + if (find == i) + return It.key(); + i++; + } + } + return ParseNode(); +} + +static ParseNode f_matrixCols(Parser* P, const ParameterList& params) +{ + QString name = params[0].toString(); + if (P->isMatrix(name)) + { + typedef QMap col_map; + col_map col_head; + uint cols = 0; + const QMap > A = P->matrix(name); + for (QMapConstIterator > It = A.begin(); It != A.end(); ++It) + { + const QMap B = It.data(); + for (QMapConstIterator It2 = B.begin(); It2 != B.end(); ++It2 ) + { + bool colfound = false; + for (QMapConstIterator It3 = col_head.begin(); It3 != col_head.end(); ++It3 ) + { + if (It2.key() == (*It3)) + { + colfound = true; + break; + } + } + if (!colfound) + { + col_head[cols] = It2.key(); + cols++; + } + } + } + return (uint)cols; + } + else + return (uint)0; +} + +static ParseNode f_matrixColumnKeys(Parser* P, const ParameterList& params) +{ + QString name = params[0].toString(); + if (!P->isMatrix(name)) + return ParseNode(); + QString matrix; + QString tmp; + QString separator = "\t"; + if (params.count() == 2) + separator = params[1].toString(); + const QMap > A = P->matrix(name); + QStringList colnames; + int c =0; + + typedef QMap col_map; + col_map col_head; + for (QMapConstIterator > It1 = A.begin(); It1 != A.end(); ++It1 ) + { + const QMap B = It1.data(); + for (QMapConstIterator It2 = B.begin(); It2 != B.end(); ++It2 ) + { + bool colfound = false; + for (QMapConstIterator It3 = col_head.begin(); It3 != col_head.end(); ++It3 ) + { + if (It2.key() == (*It3)) + { + colfound = true; + break; + } + } + if (!colfound) + { + col_head[c] = It2.key(); + if (c > 0) + matrix.append(separator); + matrix.append(It2.key()); + c++; + } + } + } + return matrix; +} + +static ParseNode f_matrixRowToArray(Parser* P, const ParameterList& params) +{ + QString mtr = params[0].toString(); + if (P->isMatrix(mtr)) + { + const QMap > A = P->matrix(mtr); + int i = 0; + int rclear = 1; + int ridx = 1; + if (params.count() > 2) + rclear = params[3].toInt(); + if (params.count() > 3) + ridx = params[4].toInt(); + QString arr = params[2].toString(); + if (rclear) + P->unsetArray(arr); + for (QMapConstIterator > It1 = A.begin(); It1 != A.end(); ++It1) + { + if (It1.key() == params[1].toString() ) + { + const QMap B = It1.data(); + for (QMapConstIterator It2 = B.begin(); It2 != B.end(); ++It2 ) + { + if (ridx) + P->setArray(arr, QString::number(i), (*It2)); + else + P->setArray(arr, It2.key(), (*It2)); + i++; + } + } + } + } + return ParseNode(); +} + +static ParseNode f_matrixColumnToArray(Parser* P, const ParameterList& params) +{ + QString name = params[0].toString(); + if (P->isMatrix(name)) + { + const QMap > A = P->matrix(name); + for (QMapConstIterator > It1 = A.begin(); It1 != A.end(); ++It1) + { + const QMap B = It1.data(); + for (QMapConstIterator It2 = B.begin(); It2 != B.end(); ++It2 ) + { + if (It2.key() == params[1].toString() ) + { + P->setArray(params[2].toString(), It1.key(), (*It2)); + } + } + } + } + return ParseNode(); +} + +static ParseNode f_matrixColumnToIndexedArray(Parser* P, const ParameterList& params) +{ + QString name = params[0].toString(); + if (P->isMatrix(name)) + { + const QMap > A = P->matrix(name); + int i = 0; + for (QMapConstIterator > It1 = A.begin(); It1 != A.end(); ++It1) + { + const QMap B = It1.data(); + for (QMapConstIterator It2 = B.begin(); It2 != B.end(); ++It2 ) + { + if (It2.key() == params[1].toString() ) + { + P->setArray(params[2].toString(), QString::number(i), (*It2)); + i++; + } + } + } + } + return ParseNode(); +} + +static ParseNode f_matrixAddRow(Parser* P, const ParameterList& params) +{ + QString name = params[0].toString(); + QString rowkey = params[1].toString(); + QStringList rows = QStringList::split("\n", params[2].toString()); + for (QStringList::Iterator itr = rows.begin(); itr != rows.end(); ++itr ) + { + QStringList cols = QStringList::split("\t", (*itr)); + if (cols.count() != 2 ) + continue; + QStringList::Iterator itc = cols.begin(); + QString rkey = (*itc).stripWhiteSpace(); + ++itc; + QString rval = (*itc).stripWhiteSpace(); + if (!rkey.isEmpty() && !rval.isEmpty()) + P->setMatrix(name, rowkey, rkey, rval); + } + return ParseNode(); +} + +static ParseNode f_matrixRemoveRow(Parser* P, const ParameterList& params) +{ + QString name = params[0].toString(); + if (!P->isMatrix(name)) + return ParseNode(); + QString rowkey = params[1].toString(); + int found = 0; + const QMap > A = P->matrix(name); + if (A.contains(rowkey)) + { + P->unsetMatrix(name, rowkey); + found = 1; + } + return QString::number(found); +} +/* +static ParseNode f_matrixAddColumn(Parser* P, const ParameterList& params) +{ +} +*/ +static ParseNode f_matrixRemoveColumn(Parser* P, const ParameterList& params) +{ + QString name = params[0].toString(); + QString colkey = params[1].toString(); + if (!P->isMatrix(name)) + return ParseNode(); + int found = 0; + const QMap > A = P->matrix(name); + for (QMapConstIterator > It = A.begin(); It != A.end(); ++It) + { + if (A[It.key()].contains(colkey)) + found = 1; + P->unsetMatrix(name, It.key(), colkey); + } + return QString::number(found); +} +/* +static ParseNode f_matrixIndexedCopy(Parser* P, const ParameterList& params) +{ +} +*/ /********** input functions *********************/ static ParseNode f_inputColor(Parser*, const ParameterList& params) { @@ -793,7 +1266,7 @@ if (params.count() > 1) caption = params[1].toString(); KMessageBox::information(0, text, caption); - return ParseNode(); + return 1; } static ParseNode f_message_error(Parser*, const ParameterList& params) @@ -804,7 +1277,7 @@ if (params.count() > 1) caption = params[1].toString(); KMessageBox::error(0, text, caption); - return ParseNode(); + return 1; } static ParseNode f_message_warning(Parser*, const ParameterList& params) @@ -915,6 +1388,7 @@ registerFunction("str_find", Function(&f_stringFind, ValueInt, ValueString, ValueString, ValueInt, 2)); registerFunction("str_findrev", Function(&f_stringFindRev, ValueInt, ValueString, ValueString, ValueInt, 2)); registerFunction("str_left", Function(&f_stringLeft, ValueString, ValueString, ValueInt)); + registerFunction("str_count", Function(&f_stringCount, ValueInt, ValueString, ValueString)); registerFunction("str_right", Function(&f_stringRight, ValueString, ValueString, ValueInt)); registerFunction("str_mid", Function(&f_stringMid, ValueString, ValueString, ValueInt, ValueInt, 2)); registerFunction("str_remove", Function(&f_stringRemove, ValueString, ValueString, ValueString)); @@ -928,6 +1402,10 @@ registerFunction("str_toint", Function(&f_stringToInt, ValueString, ValueInt, 1)); registerFunction("str_todouble", Function(&f_stringToDouble, ValueString, ValueDouble, 1)); registerFunction("str_round", Function(&f_stringRound, ValueInt, ValueDouble, ValueInt, 2)); + registerFunction("str_sort", Function(&f_stringSort, ValueString, ValueString, ValueString, 1, 2)); + registerFunction("str_trim", Function(&f_stringTrim, ValueString, ValueString, 1)); + registerFunction("str_padLeft", Function(&f_stringPadLeft, ValueString, ValueInt, ValueString, ValueString, 1, 2)); + registerFunction("str_padRight", Function(&f_stringPadRight, ValueString, ValueInt, ValueString, ValueString, 1, 2)); registerFunction("return", Function(&f_return, ValueNone, ValueString, 1, 1)); registerFunction("debug", Function(&f_debug, ValueNone, ValueString, 1, 100)); registerFunction("echo", Function(&f_echo, ValueNone, ValueString, 1, 100)); @@ -963,19 +1441,35 @@ registerFunction("array_indexedRemoveElements", Function(&f_arrayIndexedRemoveElements, ValueNone, ValueString, ValueInt, ValueInt, 2 , 3)); registerFunction("array_indexedInsertElements", Function(&f_arrayIndexedInsertElements, ValueNone, ValueString, ValueInt, ValueString, ValueString, 3, 4)); registerFunction("array_remove", Function(&f_arrayRemove, ValueNone, ValueString, ValueString)); + registerFunction("matrix_fromString", Function(&f_matrixFromString, ValueNone, ValueString, ValueString, ValueInt, ValueInt, 2, 4)); + registerFunction("matrix_toString", Function(&f_matrixToString, ValueNone, ValueString, ValueInt, ValueInt, 1, 3)); + registerFunction("matrix_clear", Function(&f_matrixClear, ValueNone, ValueString)); + registerFunction("matrix_rows", Function(&f_matrixRows, ValueInt, ValueString)); + registerFunction("matrix_columns", Function(&f_matrixCols, ValueInt, ValueString)); + registerFunction("matrix_rowToArray", Function(&f_matrixRowToArray, ValueNone, ValueString, ValueInt, ValueString, ValueInt, ValueInt, 3, 5)); + registerFunction("matrix_columnToArray", Function(&f_matrixColumnToArray, ValueNone, ValueString, ValueString, ValueString, 3, 3)); + registerFunction("matrix_columnToIndexedArray", Function(&f_matrixColumnToIndexedArray, ValueNone, ValueString, ValueString, ValueString, 3, 3)); + registerFunction("array_flipCopy", Function(&f_arrayFlipCopy, ValueNone, ValueString, ValueString, 2, 2)); + registerFunction("matrix_rowKeys", Function(&f_matrixRowKeys, ValueString, ValueString, ValueString, 1, 2)); + registerFunction("matrix_columnKeys", Function(&f_matrixColumnKeys, ValueString, ValueString, ValueString, 1, 2)); + registerFunction("matrix_addRow", Function(&f_matrixAddRow, ValueNone, ValueString, ValueString, ValueString, 3, 3)); + registerFunction("matrix_removeRow", Function(&f_matrixRemoveRow, ValueInt, ValueString, ValueString, 2, 2)); + registerFunction("matrix_removeColumn", Function(&f_matrixRemoveColumn, ValueInt, ValueString, ValueString, 2, 2)); + registerFunction("matrix_findRow", Function(&f_matrixFindRow, ValueString, ValueString, ValueString, ValueString, 3, 4)); + registerFunction("input_color", Function(&f_inputColor, ValueString, ValueString, 0)); registerFunction("input_text", Function(&f_inputText, ValueString, ValueString, ValueString, ValueString, 2)); registerFunction("input_password", Function(&f_inputPassword, ValueString, ValueString, ValueString, 1)); registerFunction("input_value", Function(&f_inputValue, ValueInt, ValueString, ValueString, ValueInt, ValueInt, - ValueInt, ValueInt, 5)); + ValueInt, ValueInt, 6)); registerFunction("input_double", Function(&f_inputValueDouble, ValueDouble, ValueString, ValueString, ValueDouble, ValueDouble, - ValueDouble, ValueDouble, 5)); + ValueDouble, ValueDouble, 6)); registerFunction("input_openfile", Function(&f_inputOpenFile, ValueString, ValueString, ValueString, ValueString, 0)); registerFunction("input_openfiles", Function(&f_inputOpenFiles, ValueString, ValueString, ValueString, ValueString, 0)); registerFunction("input_savefile", Function(&f_inputSaveFile, ValueString, ValueString, ValueString, ValueString, 0)); registerFunction("input_directory", Function(&f_inputDirectory, ValueString, ValueString, ValueString, 0)); - registerFunction("message_info", Function(&f_message_info, ValueNone, ValueString, ValueString, 1)); - registerFunction("message_error", Function(&f_message_error, ValueNone, ValueString, ValueString, 1)); + registerFunction("message_info", Function(&f_message_info, ValueInt, ValueString, ValueString, 1)); + registerFunction("message_error", Function(&f_message_error, ValueInt, ValueString, ValueString, 1)); registerFunction("message_warning", Function(&f_message_warning, ValueInt, ValueString, ValueString, ValueString, ValueString, ValueString, 1)); registerFunction("message_question", Function(&f_message_question, ValueInt, ValueString, ValueString,