Ejemplo n.º 1
0
/** Find an edge group coloring in a bipartite group graph.
 *  The algorithm used here is a variant of the menu graph method.
 *  It maintains a separate menu graph for each output, and a maximum
 *  matching for each. It also maintains a "deficit" for each edge group,
 *  which is the number of menu graphs for which the group is unmatched.
 *  It then repeatedly selects the group with the largest deficit and
 *  adjusts its menu to reduce its deficit. 
 *  Once all deficits are zero, it colors the edges based on the matchings
 *  in the menu graphs.
 *  @param g is a reference to the graph
 *  @param edgeColors is an array indexed by edge numbers which is allocated
 *  by the caller; on return edgeColors[e] is the color assigned to edge e
 *  @return the number of colors used
 */
egGmenu::egGmenu(GroupGraph& g, int edgeColors[]) : egMenu(g, edgeColors) {
	// create heap sorted by negative group size
	Dheap<int> groups(gp->M());
	for (int grp = 1; grp <= gp->M(); grp++) {
		if (gp->groupSize(grp) > 0)
			groups.insert(grp,-(gp->groupSize(grp)));
	}
	// repeatedly select next largest group and expand menu until it
	// is matched in all its menu graphs
	maxColor = max(g.maxGroupCountIn(), g.maxDegreeOut());
	while (!groups.empty()) {
		int grp = groups.deletemin();
		vertex u = gp->input(gp->firstEdgeInGroup(grp));
		int k = (maxColor + (gp->groupCount(u)-1))/gp->groupCount(u);
		while (true) {
			// select available color with the largest gain for grp
			int best = 0; int bestGain = 0;
			for (int c = avail[u].first(); c != 0 && c <= maxColor;
				 c = avail[u].next(c)) {
				int cgain = gain(c,grp);
				if (cgain > bestGain) {
					best = c; bestGain = cgain;
				}
			}
			if (bestGain <= 0 || menuSize(grp) >= k) {
				maxColor++; best = maxColor; resetMenu(grp);
				k = (maxColor + (gp->groupCount(u)-1))/
				    gp->groupCount(u);
			}
			if (growMenu(grp, best) == 0) break;
		}
	}
	for (vertex v = gp->firstOut(); v != 0; v = gp->nextOut(v)) {
		Graph& mg = *mgraf[v]; dynamicMatch& dm = *dymatch[v];
		// now color the edges using the matching
		for (edge e = gp->firstAt(v); e != 0; e = gp->nextAt(v,e)) {
			color[e] = mg.right(dm.matchEdge(gx[e]))-gp->degree(v);
		}
	}
}
Ejemplo n.º 2
0
bool GUIKeyChangeMenu::OnEvent(const SEvent& event)
{
	if (event.EventType == EET_KEY_INPUT_EVENT && activeKey >= 0
		&& event.KeyInput.PressedDown)
	{
		
		bool prefer_character = shift_down;
		KeyPress kp(event.KeyInput, prefer_character);
		
		bool shift_went_down = false;
		if(!shift_down &&
				(event.KeyInput.Key == irr::KEY_SHIFT ||
				event.KeyInput.Key == irr::KEY_LSHIFT ||
				event.KeyInput.Key == irr::KEY_RSHIFT))
			shift_went_down = true;

		// Remove Key already in use message
		if(this->key_used_text)
		{
			this->key_used_text->remove();
			this->key_used_text = NULL;
		}
		// Display Key already in use message
		if (std::find(this->key_used.begin(), this->key_used.end(), kp) != this->key_used.end())
		{
			core::rect < s32 > rect(0, 0, 600, 40);
			rect += v2s32(0, 0) + v2s32(25, 30);
			const wchar_t *text = wgettext("Key already in use");
			this->key_used_text = Environment->addStaticText(text,
					rect, false, true, this, -1);
			delete[] text;
			//infostream << "Key already in use" << std::endl;
		}

		// But go on
		{
			key_setting *k = NULL;
			for(size_t i = 0; i < key_settings.size(); i++)
			{
				if(key_settings.at(i)->id == activeKey)
				{
					k = key_settings.at(i);
					break;
				}
			}
			FATAL_ERROR_IF(k == NULL, "Key setting not found");
			k->key = kp;
			const wchar_t *text = wgettext(k->key.name());
			k->button->setText(text);
			delete[] text;

			this->key_used.push_back(kp);

			// Allow characters made with shift
			if(shift_went_down){
				shift_down = true;
				return false;
			}else{
				activeKey = -1;
				return true;
			}
		}
	}
	if (event.EventType == EET_GUI_EVENT)
	{
		if (event.GUIEvent.EventType == gui::EGET_ELEMENT_FOCUS_LOST
			&& isVisible())
		{
			if (!canTakeFocus(event.GUIEvent.Element))
			{
				dstream << "GUIMainMenu: Not allowing focus change."
				<< std::endl;
				// Returning true disables focus change
				return true;
			}
		}
		if (event.GUIEvent.EventType == gui::EGET_BUTTON_CLICKED)
		{
			switch (event.GUIEvent.Caller->getID())
			{
				case GUI_ID_BACK_BUTTON: //back
					acceptInput();
					quitMenu();
					return true;
				case GUI_ID_ABORT_BUTTON: //abort
					quitMenu();
					return true;
				default:
					key_setting *k = NULL;
					for(size_t i = 0; i < key_settings.size(); i++)
					{
						if(key_settings.at(i)->id == event.GUIEvent.Caller->getID())
						{
							k = key_settings.at(i);
							break;
						}
					}
					FATAL_ERROR_IF(k == NULL, "Key setting not found");

					resetMenu();
					shift_down = false;
					activeKey = event.GUIEvent.Caller->getID();
					const wchar_t *text = wgettext("press key");
					k->button->setText(text);
					delete[] text;
					this->key_used.erase(std::remove(this->key_used.begin(),
							this->key_used.end(), k->key), this->key_used.end());
					break;
			}
			Environment->setFocus(this);
		}
	}
	return Parent ? Parent->OnEvent(event) : false;
}
Ejemplo n.º 3
0
bool GUISettingsMenu::OnEvent(const SEvent& event)
{
	if (event.EventType == EET_KEY_INPUT_EVENT && activeKey >= 0 && event.KeyInput.PressedDown) {
		KeyPress kp(event.KeyInput);
		gui::IGUIElement *e = getElementFromId(activeKey);
		if (e != NULL && e->getType() == gui::EGUIET_BUTTON) {
			e->setEnabled(true);
			e->setText(kp.guiName().c_str());
			keys[activeKey-GUI_ID_KEYSETTINGS_BASE] = kp;
		}
		activeKey = -1;
		return true;
	}
	if (event.EventType == EET_GUI_EVENT) {
		if (event.GUIEvent.EventType == gui::EGET_ELEMENT_FOCUS_LOST && isVisible()) {
			if (!canTakeFocus(event.GUIEvent.Element)) {
				dstream << "GUIMainMenu: Not allowing focus change."
						<< std::endl;
				// Returning true disables focus change
				return true;
			}
		}
		if (event.GUIEvent.EventType==gui::EGET_CHECKBOX_CHANGED) {
			acceptInput();
			m_accepted = false;
			regenerateGui(m_screensize);
		}
		if (event.GUIEvent.EventType == gui::EGET_BUTTON_CLICKED) {
			s32 id = event.GUIEvent.Caller->getID();
			if (id >= GUI_ID_KEYSETTINGS_BASE) {
				resetMenu();
				activeKey = id;
				gui::IGUIElement *e = getElementFromId(id);
				if (e != NULL && e->getType() == gui::EGUIET_BUTTON) {
					e->setText(wgettext("press Key"));
					e->setEnabled(false);
					return true;
				}
			}else{
				switch (event.GUIEvent.Caller->getID()) {
				case GUI_ID_TAB_SETTINGS_CONTROLS:
					acceptInput();
					m_accepted = false;
					m_data.selected_tab = TAB_SETTINGS_CONTROLS;
					regenerateGui(m_screensize);
					return true;
				case GUI_ID_TAB_SETTINGS_GRAPHICS:
					acceptInput();
					m_accepted = false;
					m_data.selected_tab = TAB_SETTINGS_GRAPHICS;
					regenerateGui(m_screensize);
					return true;
				case GUI_ID_TAB_SETTINGS_VIDEO:
					acceptInput();
					m_accepted = false;
					m_data.selected_tab = TAB_SETTINGS_VIDEO;
					regenerateGui(m_screensize);
					return true;
				case GUI_ID_TAB_SETTINGS_SOUND:
					acceptInput();
					m_accepted = false;
					m_data.selected_tab = TAB_SETTINGS_SOUND;
					regenerateGui(m_screensize);
					return true;
				case GUI_ID_TAB_MAINMENU: //back
					acceptInput();
					save();
					quitMenu();
					return true;
				}
			}
		}
		if (event.GUIEvent.EventType == gui::EGET_SCROLL_BAR_CHANGED) {
			switch (event.GUIEvent.Caller->getID()) {
			case GUI_ID_VOLUME_SB:
				gui::IGUIElement *vsb = getElementFromId(GUI_ID_VOLUME_SB);
				if(vsb != NULL && vsb->getType() == gui::EGUIET_SCROLL_BAR) {
					m_data.volume = (float)((gui::IGUIScrollBar*)vsb)->getPos();
					if (g_sound)
						g_sound->setListenerGain(m_data.volume/100.0);
				}
				return true;
			}
		}
	}
	return Parent ? Parent->OnEvent(event) : false;
}
Ejemplo n.º 4
0
bool GUIKeyChangeMenu::OnEvent(const SEvent& event)
{
	if (event.EventType == EET_KEY_INPUT_EVENT && activeKey >= 0
			&& event.KeyInput.PressedDown)
	{
		changeCtype("");
		KeyPress kp(event.KeyInput);

		if (activeKey == GUI_ID_KEY_FORWARD_BUTTON)
		{
			this->forward->setText(wgettext(kp.name()));
			this->key_forward = kp;
		}
		else if (activeKey == GUI_ID_KEY_BACKWARD_BUTTON)
		{
			this->backward->setText(wgettext(kp.name()));
			this->key_backward = kp;
		}
		else if (activeKey == GUI_ID_KEY_LEFT_BUTTON)
		{
			this->left->setText(wgettext(kp.name()));
			this->key_left = kp;
		}
		else if (activeKey == GUI_ID_KEY_RIGHT_BUTTON)
		{
			this->right->setText(wgettext(kp.name()));
			this->key_right = kp;
		}
		else if (activeKey == GUI_ID_KEY_JUMP_BUTTON)
		{
			this->jump->setText(wgettext(kp.name()));
			this->key_jump = kp;
		}
		else if (activeKey == GUI_ID_KEY_SNEAK_BUTTON)
		{
			this->sneak->setText(wgettext(kp.name()));
			this->key_sneak = kp;
		}
		else if (activeKey == GUI_ID_KEY_DROP_BUTTON)
		{
			this->dropbtn->setText(wgettext(kp.name()));
			this->key_drop = kp;
		}
		else if (activeKey == GUI_ID_KEY_INVENTORY_BUTTON)
		{
			this->inventory->setText(wgettext(kp.name()));
			this->key_inventory = kp;
		}
		else if (activeKey == GUI_ID_KEY_CHAT_BUTTON)
		{
			this->chat->setText(wgettext(kp.name()));
			this->key_chat = kp;
		}
		else if (activeKey == GUI_ID_KEY_CMD_BUTTON)
		{
			this->cmd->setText(wgettext(kp.name()));
			this->key_cmd = kp;
		}
		else if (activeKey == GUI_ID_KEY_CONSOLE_BUTTON)
		{
			this->console->setText(wgettext(kp.name()));
			this->key_console = kp;
		}
		else if (activeKey == GUI_ID_KEY_RANGE_BUTTON)
		{
			this->range->setText(wgettext(kp.name()));
			this->key_range = kp;
		}
		else if (activeKey == GUI_ID_KEY_FLY_BUTTON)
		{
			this->fly->setText(wgettext(kp.name()));
			this->key_fly = kp;
		}
		else if (activeKey == GUI_ID_KEY_FAST_BUTTON)
		{
			this->fast->setText(wgettext(kp.name()));
			this->key_fast = kp;
		}
		else if (activeKey == GUI_ID_KEY_USE_BUTTON)
		{
			this->use->setText(wgettext(kp.name()));
			this->key_use = kp;
		}
		else if (activeKey == GUI_ID_KEY_DUMP_BUTTON)
		{
			this->dump->setText(wgettext(kp.name()));
			this->key_dump = kp;
		}
		changeCtype("C");
		activeKey = -1;
		return true;
	}
	if (event.EventType == EET_GUI_EVENT)
	{
		if (event.GUIEvent.EventType == gui::EGET_ELEMENT_FOCUS_LOST
				&& isVisible())
		{
			if (!canTakeFocus(event.GUIEvent.Element))
			{
				dstream << "GUIMainMenu: Not allowing focus change."
						<< std::endl;
				// Returning true disables focus change
				return true;
			}
		}
		if (event.GUIEvent.EventType == gui::EGET_BUTTON_CLICKED)
		{
			if(event.GUIEvent.Caller->getID() != GUI_ID_BACK_BUTTON &&
				event.GUIEvent.Caller->getID() != GUI_ID_ABORT_BUTTON)
			{
				changeCtype("");
			}

			switch (event.GUIEvent.Caller->getID())
			{
			case GUI_ID_BACK_BUTTON: //back
				acceptInput();
				quitMenu();
				return true;
			case GUI_ID_ABORT_BUTTON: //abort
				quitMenu();
				return true;
			case GUI_ID_KEY_FORWARD_BUTTON:
				resetMenu();
				activeKey = event.GUIEvent.Caller->getID();
				this->forward->setText(wgettext("press Key"));
				break;
			case GUI_ID_KEY_BACKWARD_BUTTON:
				resetMenu();
				activeKey = event.GUIEvent.Caller->getID();
				this->backward->setText(wgettext("press Key"));
				break;
			case GUI_ID_KEY_LEFT_BUTTON:
				resetMenu();
				activeKey = event.GUIEvent.Caller->getID();
				this->left->setText(wgettext("press Key"));
				break;
			case GUI_ID_KEY_RIGHT_BUTTON:
				resetMenu();
				activeKey = event.GUIEvent.Caller->getID();
				this->right->setText(wgettext("press Key"));
				break;
			case GUI_ID_KEY_USE_BUTTON:
				resetMenu();
				activeKey = event.GUIEvent.Caller->getID();
				this->use->setText(wgettext("press Key"));
				break;
			case GUI_ID_KEY_FLY_BUTTON:
				resetMenu();
				activeKey = event.GUIEvent.Caller->getID();
				this->fly->setText(wgettext("press Key"));
				break;
			case GUI_ID_KEY_FAST_BUTTON:
				resetMenu();
				activeKey = event.GUIEvent.Caller->getID();
				this->fast->setText(wgettext("press Key"));
				break;
			case GUI_ID_KEY_JUMP_BUTTON:
				resetMenu();
				activeKey = event.GUIEvent.Caller->getID();
				this->jump->setText(wgettext("press Key"));
				break;
			case GUI_ID_KEY_DROP_BUTTON:
				resetMenu();
				activeKey = event.GUIEvent.Caller->getID();
				this->dropbtn->setText(wgettext("press Key"));
				break;
			case GUI_ID_KEY_CHAT_BUTTON:
				resetMenu();
				activeKey = event.GUIEvent.Caller->getID();
				this->chat->setText(wgettext("press Key"));
				break;
			case GUI_ID_KEY_CMD_BUTTON:
				resetMenu();
				activeKey = event.GUIEvent.Caller->getID();
				this->cmd->setText(wgettext("press Key"));
				break;
			case GUI_ID_KEY_CONSOLE_BUTTON:
				resetMenu();
				activeKey = event.GUIEvent.Caller->getID();
				this->console->setText(wgettext("press Key"));
				break;
			case GUI_ID_KEY_SNEAK_BUTTON:
				resetMenu();
				activeKey = event.GUIEvent.Caller->getID();
				this->sneak->setText(wgettext("press Key"));
				break;
			case GUI_ID_KEY_INVENTORY_BUTTON:
				resetMenu();
				activeKey = event.GUIEvent.Caller->getID();
				this->inventory->setText(wgettext("press Key"));
				break;
			case GUI_ID_KEY_DUMP_BUTTON:
				resetMenu();
				activeKey = event.GUIEvent.Caller->getID();
				this->dump->setText(wgettext("press Key"));
				break;
			case GUI_ID_KEY_RANGE_BUTTON:
				resetMenu();
				activeKey = event.GUIEvent.Caller->getID();
				this->range->setText(wgettext("press Key"));
				break;
			}
			//Buttons
			changeCtype("C");

		}
	}
	return Parent ? Parent->OnEvent(event) : false;
}
Ejemplo n.º 5
0
void FWMenu::useMenu() {

  unsigned long value;          // To provide (long)selection[p].value.

  // Populate the buttonz private member variable.
  setButtonz(getButtons());

  // Menu functionality - Display and set values.
  //=============================================
  // B1 - Spare at present.
  if (aButtonPressed(button1)) {
    //Later this will be used to start a cycle.
  }

  // B2 - Up/--.
  if (aButtonPressed(button2)) {
    if (mode == 'o') {
      if (p > 0) {   // Not at top?
        p--;        // Move up 1 cell.
      }
      String s = selection[p].option;
      setDisplayToString(s);
    }
    if (mode == 'v') {
      if (selection[p].access == 'w') {
        // Don't allow a decrement below zero
        float testval = selection[p].value - selection[p].delta;
        if (testval >= 0)
          selection[p].value -= selection[p].delta;
        // Display value.
        value = (unsigned long)(selection[p].value * 10);
        setDisplayToDecNumber(value, 2, false);
      }
    }
  }

  // B3 - Down/++.
  if (aButtonPressed(button3)) {
    if (mode == 'o') {
      if (p < n - 1) { // Not at bottom?
        p++;        // Move down 1 cell.
      }
      String s = selection[p].option;
      setDisplayToString(s);
    }
    if (mode == 'v') {
      if (selection[p].access == 'w') {
        selection[p].value += selection[p].delta;
        // Display value.
        value = (unsigned long)(selection[p].value * 10);
        setDisplayToDecNumber(value, 2, false);          // provided cast value here
      }
    }
  }

  // B4 - <Enter> and swap modes.
  if (aButtonPressed(button4)) {
    if (mode == 'o') {
      mode = 'v';
      // Display value.
      value = (unsigned long)(selection[p].value * 10);
      setDisplayToDecNumber(value, 2, false);
    }
    else if (mode == 'v') {
      mode = 'o';
      // Display option.
      setDisplayToString(selection[p].option);
    }
  }

  // B5 - Clear display
  if (aButtonPressed(button5)) {
    showDisplay = !showDisplay;
    if (!showDisplay) {
      clearDisplay();
    }
    mode = 'o'; // We always 'switch on' (display something on the LED's) again in 'Option Mode'.
    // A little trick here - when you switch back on using B2 or B3, press each of these buttons once to return to where you were.
  }

  // B8 - Reset menu to default values
  if (aButtonPressed(button8)) {
    resetMenu();
    setDisplayToString("DEFAULTS");
  }


  delay(_pace);   // How fast the display changes.
}
Ejemplo n.º 6
0
e_scriptresult TScript::loadScript2(QString includeFile, QString parent)
{
    QString fn = filename;
    if (includeFile.isEmpty()) {
        qDebug() << "Running loadScript() on" << filename;
        scriptstr.clear();
        errorKeyword.clear();
        curLine = 1;
        loadIntLine = 1;
        include.clear();
        command.clear();
        tevent.clear();
        lineMap.clear();

        QHashIterator<QString,TCustomScriptDialog*> i(dialogs);
        while (i.hasNext()) {
            i.next();
            delete i.value();
        }
        dialogs.clear();

    }
    else {
        fn = setRelativePath(parent, includeFile);
        qDebug() << "Including" << fn;
    }

    qDebug() << "attempt:" << fn;

    if (QFile::exists(fn) == false)
    return se_FileNotExist;

    QFile f(fn);
    bool fo = f.open(QIODevice::ReadOnly | QIODevice::Text);
    if (fo == false)
        return se_FileCannotOpen;

    QString ba = f.readAll();
    if (ba.length() < 1)
        return se_FileEmpty;

    // Remove comments, keep newlines:
    QString tmp;
    bool isCommented = false;

    QString lineFile = includeFile;
    if (lineFile.isEmpty())
        lineFile = filename;

    int cLine = 1;

    for (int i = 0; i <= ba.length()-1; ++i) {
        QChar c = ba[i];

        if (c == '\n') { // newline
            delWhitespace(&tmp);

            lineMap.insert(loadIntLine, QString("%1:%2")
                                          .arg(cLine)
                                          .arg(lineFile)
                           );

            if (tmp.length() > 0) {
                scriptstr.push_back(tmp + '\n');
                loadIntLine++;
            }

            cLine++;

            isCommented = false;
            tmp.clear();
            continue;
        }

        if (isCommented) // part of a comment, ignore.
            continue;

        if (c == ';') { // comment, skip anything after.
            isCommented = true;
            continue;
        }

        tmp.append(c);
    }

    if (tmp.length() > 0) // insert anything missing from very last line.
        scriptstr.push_back(tmp + '\n');

    // This was an include, the first instance of loadScript() will take care of retreiving the rest.
    if (includeFile.length() > 0)
        return se_None;


    // Search script for functions and parse the meta.
    QString keyword;
    bool getKeyword = true; // Always begin with getting keyword.
    bool comment = false;

    enum { // Expecting
        ex_Unknown = 0, // If we use this we must pose an error too.
        ex_Block,
        ex_Brace,
        ex_Statement,
        ex_Ignore, // ignore until next block (still handles nesting levels)
        ex_Include = 5,
        ex_Command,
        ex_Event,
        ex_Timer,
        ex_ScriptName,
        ex_FunctionName = 10,
        ex_MenuType,
        ex_MenuTitle,
        ex_MenuFunction,
        ex_DialogName,
        ex_DialogTitle = 15,
        ex_DialogGeometry,
        ex_DialogEmbed,
        ex_DialogIcon,
        ex_DialogLabel,
        ex_DialogButton = 20,
        ex_DialogEditBox,
        ex_DialogTextBox,
        ex_DialogListBox,
        ex_DialogPaint,
        ex_DialogText = 25
    };

    enum {
        st_None = 0, // used when waiting for block name keyword
        st_Meta,
        st_Function,
        st_Menu,
        st_Dialog
    };

    int state = st_None;
    int ex = ex_Block; // We expect to find a script block to begin with. either function, script or menu.
    int n = 0; // Nesting level. 0 is where script blocks are at (script, function, menu, etc.)

    QString temp[3];
    TCustomScriptDialog *dialog = NULL;

    // Reset the custom menues, they'll be set up later on in here...
    resetMenu(customNicklistMenu);
    resetMenu(customChannelMenu);
    resetMenu(customQueryMenu);
    resetMenu(customStatusMenu);

    fnindex.clear(); // re-load function index

    for (int i = 0; i <= scriptstr.length()-1; ++i) {
        QChar cc = scriptstr[i];

        errorKeyword = keyword + cc;

        if (cc == '\n')
            curLine++;

        if (ex != ex_Ignore) {
            if (cc == '\\') { // Escape, skip completely and add to keyword
                if ((i == scriptstr.length()-1) || (scriptstr[i+1] == '\n'))
                    return se_EscapeOnEndLine;

                keyword += scriptstr[i+1];
                i++;
                continue;
            }

            /* Comment handling */
            /* Put ; anywhere but must end with newline. */
            if (cc == '\n')
                comment = false;
            if (comment)
                continue;
            if (cc == ';') {
                comment = true;
                continue;
            }
            /* **************** */
        }



        if (cc == '{') {
            if ((ex != ex_Brace) && (ex != ex_Ignore) && (n == 0))
                return se_UnexpectedToken;
            n++;
        }
        if (cc == '}') {
            if (n == 0)
                return se_UnexpectedToken;

            n--;

            if (state == st_Dialog) {
                dialogs.insert( dialog->getName(), dialog );
                connect(dialog, SIGNAL(runEvent(e_iircevent,QStringList)),
                this, SLOT(runEvent(e_iircevent,QStringList)));
                state = st_None;
            }

            if (n == 0)
            ex = ex_Block;
        }

        if (ex == ex_Brace) {
            if ((cc != ' ') && (cc != '\t') && (cc != '\n') && (cc != '{') && (cc != '}'))
                return se_UnexpectedToken;

            if ((cc == ' ') || (cc == '\t') || (cc == '\n'))
                continue;

            ex = ex_Statement;
            continue;
        }

        if (cc == '}')
            continue;

        if (ex == ex_FunctionName) {
            // Stop this one at (
            // If we encounter \n first, pose error.

            if (cc == '\n')
                return se_UnexpectedNewline;
            if (i == scriptstr.length()-1)
                return se_UnexpectedFinish;

            if (cc == '(') {
                fnindex.insert(keyword.toUpper(), i);
                ex = ex_Ignore;
                continue;
            }

            if (cc == ' ') {
                QChar cc2 = scriptstr[i+1];
                if (cc2 == '(')
                    continue;
                else
                    return se_UnexpectedToken;
            }
        }

        // Newline, receiving keyword but keyword got is none. ignore.
        if ((cc == '\n') && (getKeyword == true) && (keyword.length() == 0))
            continue;

        // Newline, space receiving keyword and got a keyword. parse.
        if (((cc == '\n') || (cc == ' ')) && (getKeyword == true) && (keyword.length() >= 0)) {
            QString keywup = keyword.toUpper();

            if (n == 0) { // Here we always expect script blocks.
                if (ex == ex_Block) {

                    if (keywup == "SCRIPT") {
                        ex = ex_ScriptName;
                        state = st_Meta;
                        keyword.clear();
                        continue;
                    }

                    else if (keywup == "META") {
                        ex = ex_Brace;
                        state = st_Meta;
                        keyword.clear();
                        continue;
                    }

                    else if (keywup == "FUNCTION") {
                        ex = ex_FunctionName;
                        state = st_Function;
                        keyword.clear();
                        continue;
                    }

                    else if (keywup == "MENU") {
                        ex = ex_MenuType;
                        state = st_Menu;
                        keyword.clear();
                        continue;
                    }

                    else if (keywup == "DIALOG") {
                        ex = ex_DialogName;
                        state = st_Dialog;
                        keyword.clear();
                        continue;
                    }

                    else
                        return se_InvalidBlockType;
                }

                if (ex == ex_ScriptName) {
                    name = keyword;
                    ex = ex_Brace;
                    keyword.clear();
                    continue;
                }

                if (ex == ex_DialogName) {
                    dialog =  new TCustomScriptDialog(this, keyword, dlgParent);
                    ex = ex_Brace;
                    keyword.clear();
                    continue;
                }

                if (ex == ex_MenuType) {
                    temp[0] = keyword.toUpper();
                    state = st_Menu;
                    ex = ex_Brace;
                    continue;
                }

            }

            if (n > 0) {

                if (state == st_Meta) {

                    if (ex == ex_Statement) {
                        keyword.clear(); // this is safe here.
                        if (keywup == "INCLUDE") {
                            ex = ex_Include;
                            continue;
                        }
                        else if (keywup == "COMMAND") {
                            ex = ex_Command;
                            continue;
                        }
                        else if (keywup == "EVENT") {
                            ex = ex_Event;
                            continue;
                        }
                        else if (keywup == "TIMER") {
                            ex = ex_Timer;
                            continue;
                        }
                        else
                            return se_InvalidMetaCommand;
                    }

                    if (ex == ex_Include) {
                        if (cc == ' ') {
                            keyword += cc;
                            continue;
                        }
                        include.push_back(keyword);
                        e_scriptresult r = loadScript2(keyword, fn);
                        keyword.clear();
                        ex = ex_Statement;

                        if (r != se_None)
                            return r;

                        continue;
                    }

                    if ((ex == ex_Command) || (ex == ex_Event) || (ex == ex_Timer)) {

                        if (temp[0].length() == 0)
                            temp[0] = keyword; // command name
                        else
                            temp[1] = keyword; // function
                        keyword.clear();

                        if (((temp[0].length() == 0) || (temp[1].length() == 0)) && (cc == '\n'))
                            return se_UnexpectedNewline;

                        if (cc == '\n') {
                            // this one will run if both temp are filled.

                            if (ex == ex_Command)
                            command.insert(temp[0].toUpper(), temp[1]);

                            if (ex == ex_Event) {
                                e_iircevent evt = getEvent(temp[0]);

                                if (evt == te_noevent)
                                    return se_InvalidEvent;

                                tevent.insertMulti(evt, temp[1]);
                            }


                            if (ex == ex_Timer) {
                                if (timers.contains(temp[0].toUpper()) == true)
                                    goto loadScript__ex_TimerAdd_Cleanup;


                                TTimer *tmr = new TTimer(temp[1].toUpper(), this);
                                connect(tmr, SIGNAL(timeout(QString)),
                                this, SLOT(timerTimeout(QString)));

                                timers.insert(temp[0].toUpper(), tmr);
                            }

                            loadScript__ex_TimerAdd_Cleanup:

                            ex = ex_Statement;
                            temp[0].clear();
                            temp[1].clear();

                            keyword.clear();
                            continue;
                        }

                        keyword.clear();
                        continue;
                    }

                }

                if (state == st_Dialog) {

                    if (ex == ex_Statement) {
                        keyword.clear();

                        if (keywup == "TITLE")
                            ex = ex_DialogTitle;

                        else if (keywup == "GEOMETRY")
                            ex = ex_DialogGeometry;

                        else if (keywup == "EMBED") {
                            // embed c|l|p|s
                            // channel, listbox, pm, status
                            ex = ex_DialogEmbed;
                        }

                        else if (keywup == "PAINT") {
                            // paint @wname x y w h
                        }

                        else if (keywup == "TEXT") {
                            // text @name x y w h
                        }

                        else if (keywup == "LABEL")
                            ex = ex_DialogLabel;

                        else if (keywup == "BUTTON")
                            ex = ex_DialogButton;

                        else if (keywup == "EDITBOX")
                            ex = ex_DialogEditBox;

                        else if (keywup == "TEXTBOX")
                            ex = ex_DialogTextBox;

                        else if (keywup == "LISTBOX")
                            ex = ex_DialogListBox;

                        else
                            return se_UnexpectedToken;

                        continue;
                    }

                    if (ex == ex_DialogTitle) {
                        for (; i <= scriptstr.length()-1; i++) {
                            QChar c = scriptstr[i];
                            if (c == '\n')
                                break;
                            keyword += c;
                        }
                        dialog->setTitle(keyword);
                        keyword.clear();
                        ex = ex_Statement;
                        continue;
                    }

                    if (ex == ex_DialogGeometry) {
                        int param = 2; // 1X 2Y 3W 4H
                        int X, Y, W, H;
                        X = keyword.toInt();
                        keyword.clear();
                        for (i++; i <= scriptstr.length()-1; i++) {
                            QChar c = scriptstr[i];

                            if ((c == ' ') || (c == '\n')) {
                                if (param == 2)
                                    Y = keyword.toInt();
                                if (param == 3)
                                    W = keyword.toInt();
                                if (param == 4)
                                    H = keyword.toInt();
                                keyword.clear();
                                param++;
                            }

                            if (c == '\n')
                                break;


                            if (param == 5)
                                break;

                            keyword += c;
                        }

                        if (param != 5)
                            return se_InvalidParamCount;

                        dialog->setGeometry(X, Y, W, H);
                        keyword.clear();
                        ex = ex_Statement;
                        continue;
                    }
                    
                    if (ex == ex_DialogEmbed) {
                        
                    }

                    if (ex >= ex_DialogLabel) {
                        int param = 2;
                        int X, Y, W, H = 0;
                        QString oname = keyword;
                        QString arg;
                        keyword.clear();
                        for (i++; i <= scriptstr.length()-1; i++) {
                            QChar c = scriptstr[i];

                            if (param < 6) {
                                if ((c == ' ') || (c == '\n')) {
                                    if (param == 2)
                                        X = keyword.toInt();
                                    if (param == 3)
                                        Y = keyword.toInt();
                                    if (param == 4)
                                        W = keyword.toInt();
                                    if (param == 5)
                                        H = keyword.toInt();
                                    keyword.clear();
                                    param++;
                                }

                            }
                            if (c == '\n')
                                break;

                            if (param >= 6)
                                arg += c;
                            else
                                keyword += c;
                        }

                        if (param != 6)
                            return se_InvalidParamCount;

                        arg = arg.mid(1);


                        if (ex == ex_DialogLabel)
                            dialog->addLabel(oname, X, Y, W, H, arg);

                        if (ex == ex_DialogButton)
                            dialog->addButton(oname, X, Y, W, H, arg);

                        if (ex == ex_DialogEditBox)
                            dialog->addEditbox(oname, X, Y, W, H);

                        if (ex == ex_DialogTextBox)
                            dialog->addTextbox(oname, X, Y, W, H);

                        if (ex == ex_DialogListBox)
                            dialog->addListbox(oname, X, Y, W, H);


                        keyword.clear();
                        ex = ex_Statement;
                        continue;
                    }

                }

                if (state == st_Menu) {
                    if (ex == ex_Statement) {
                        if (temp[0] == "NICKLIST")
                            createMenu(i, 'n');
                        if (temp[0] == "CHANNEL")
                            createMenu(i, 'c');
                        if (temp[0] == "QUERY")
                            createMenu(i, 'q');
                        if (temp[0] == "STATUS")
                            createMenu(i, 's');

                        --i;
                        temp[0].clear();
                        state = st_None;
                        ex = ex_Brace;
                    }
                }
            }

            keyword.clear();

            continue;
        }

        keyword += cc;
    }

    if (n > 0)
    return se_UnexpectedFinish;

    qDebug() << "Script" << name << "(re)loaded with:";
    qDebug() << " -" << fnindex.count() << "functions.";
    qDebug() << " -" << tevent.count() << "events.";
    qDebug() << " -" << include.count() << "includes.";
    qDebug() << " -" << command.count() << "commands.";
    qDebug() << " -" << timers.count() << "timers.";
    qDebug() << " -" << dialogs.count() << "dialogs.";
    qDebug() << "---";

    return se_None;
}