/*************************************************************************** * Copyright (C) 2005 by Daniel Stöckel * * the_docter@gmx.net * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include "configuration.h" #include #include #include #include #include #include #include #include "menulistviewitem.h" Config::Config() :mTintColor(Qt::black),mOpacity(0.2f),mScheme("none"),mMenuButtonSize(32),mNavButtonSize(32),mMenuRadius(132),doc(NULL) { mConfigPath = locate("data", "kommando/kommandorc"); kdDebug() << "kommandorc located: " << mConfigPath << endl; if (mConfigPath.isNull() || !QFile::exists(mConfigPath)){ //test for new config file kdDebug() << "There is no kommandorc in kdedirs" << endl; mConfigPath = locateLocal("data", "kommando/kommandorc"); if(QFile::exists(KShell::homeDir("")+"/.kommandorc")){ //tries old config file kdDebug() << "There is a kommandorc in homedir, moving it to " << mConfigPath << endl; QDir dir; if (!dir.rename(KShell::homeDir("")+"/.kommandorc", mConfigPath)) { kdWarning() << "Moving ~/.kommandorc failed, creating a default one" << endl; createDefaultConfigFile(); } } else { kdDebug() << "There is no kommandorc, creating a default one" << endl; createDefaultConfigFile(); } } } Config::~Config() { if(doc){ delete doc; } } void Config::createDefaultConfigFile() { setDefaultValues(); writeConfigFile(); } bool Config::readConfigFile( ) { QFile file(mConfigPath); if(!file.open(IO_ReadOnly)){ return false; } if(doc){ delete doc; } doc = new QDomDocument(); doc->setContent( &file ); file.close(); if(doc){ QDomNode topLevelNode = doc->documentElement().firstChild(); while(!topLevelNode.isNull()){ if(topLevelNode.isElement()){ QDomElement elem = topLevelNode.toElement(); if(elem.tagName()=="access"){ setShortcut(elem.text()); } else if(elem.tagName()=="tintcolor"){ mTintColor.setNamedColor(elem.text()); } else if(elem.tagName()=="opacity"){ mOpacity = elem.text().toFloat(); }else if(elem.tagName()=="menubuttonsize"){ mMenuButtonSize=elem.text().toInt(); }else if(elem.tagName()=="navbuttonsize"){ mNavButtonSize=elem.text().toInt(); }else if(elem.tagName()=="menuradius"){ mMenuRadius=elem.text().toInt(); }else if(elem.tagName()=="scheme"){ mScheme=elem.text(); } } topLevelNode = topLevelNode.nextSibling(); } } return true; } bool Config::writeConfigFile( ) { if(!doc){ return false; } mConfigPath = locateLocal("data", "kommando/kommandorc"); QFile file(mConfigPath); if(!file.open(IO_WriteOnly)){ return false; } QTextStream str(&file); str << *doc; file.close(); return true; } void Config::fromConfigDlg(KommandoViewList& listViews ) { if(doc){ delete doc; } doc = new QDomDocument(); QDomElement root=doc->createElement("root"); doc->appendChild(root); newNode("access",root,Shortcut(),"method","shortcut"); newNode("menubuttonsize",root,mMenuButtonSize); newNode("navbuttonsize",root,mNavButtonSize); newNode("tintcolor",root,tintColor().name()); newNode("opacity",root,mOpacity); newNode("menuradius",root,static_cast(mMenuRadius)); newNode("scheme",root,mScheme); for(KommandoView* it = listViews.first(); it != 0; it = listViews.next()){ if(it->childCount() > 0){ QDomElement node = newMenu(root,it->appName()); QListViewItem* temp = it->firstChild(); while(temp){ menuItemToXML(node,static_cast(temp)); temp=temp->nextSibling(); } root.appendChild(node); } } } //ARGHHH!! I need this function because QListView::lastItem returns not only top level items but also children of top level items //It took me hours of my precious lifetime to figure that out!! _Terribly_ annoying -.- QListViewItem* lastChild(QListView* view) { QListViewItem* temp=view->firstChild(); QListViewItem* item=NULL; while(temp!=NULL){ item=temp; temp=temp->nextSibling(); } return item; } void Config::toListView(KommandoViewList& listViews, QWidgetStack* listViewParent)//QListView* listView ) { if(doc){ QDomNode topLevelNode = doc->documentElement().firstChild(); const QObjectList *children = listViewParent->children(); if (children != 0) { QObjectListIterator it(*children); for (; *it != 0; ++it) listViewParent->removeWidget(static_cast(*it)); } while(!topLevelNode.isNull()){ if(topLevelNode.isElement()){ if(topLevelNode.toElement().tagName()=="menu") { KommandoView* view = new KommandoView(listViewParent,topLevelNode.toElement().attribute("appname")); listViewParent->addWidget(view); QDomNode menuNode = topLevelNode.firstChild(); while(!menuNode.isNull()){ if(menuNode.isElement()){ QDomElement elemNode=menuNode.toElement(); menuItemFromXML(view,lastChild(view),menuNode.toElement()); } menuNode = menuNode.nextSibling(); } listViews.append(view); } } topLevelNode = topLevelNode.nextSibling(); } } } void Config::toKommandoMenu(Kommando* buttonParent) { QPtrList topLevelMenus; Menu* defaultMenu = 0; if(doc){ QDomNode node = doc->documentElement().firstChild(); while(!node.isNull()){ if(node.isElement()&&(node.toElement().tagName() == "menu")){ Menu* mainMenu = menuFromXML(node.toElement(),buttonParent); if((mainMenu->appName() == "default") || (mainMenu->appName() == QString::null)){ defaultMenu = mainMenu; } mainMenu->arrangeButtons(); topLevelMenus.append(mainMenu); } node = node.nextSibling(); } for(Menu* it = topLevelMenus.first(); it != 0; it = topLevelMenus.next()){ if(it != defaultMenu){ SubmenuButton* button = new SubmenuButton(buttonParent,defaultMenu,mMenuButtonSize); button->hide(); button->setIcon("up"); //This registers the button with the Menu, but does not add it to its child List //Doing so would cause the menu to delete the default menu, which already deletes itsself it->insertNoChild(button); it->arrangeButtons(); } } buttonParent->resize(); buttonParent->setTopLevelMenus(topLevelMenus); buttonParent->setNavButtonSize(mNavButtonSize); } } void Config::setDefaultValues() { setTintColor(Qt::black); setOpacity(0.2f); setShortcut("Alt+Ctrl+H"); setNavButtonSize(32); setMenuButtonSize(32); setMenuRadius(132); setScheme("Normal"); if(doc){ delete doc; } doc = new QDomDocument(); QDomElement root = doc->createElement("root"); doc->appendChild(root); newNode("access",root,Shortcut(),"method","shortcut"); newNode("menubuttonsize",root,32); newNode("navbuttonsize",root,32); newNode("tintcolor",root,"#000000"); newNode("opacity",root,0.2f); newNode("menuradius",root,132); newNode("scheme",root,"Normal"); QDomElement node= newMenu(root,"default"); newButton(node,"konsole","konsole --workdir $HOME"); newButton(node,"kwrite","kwrite"); newButton(node,"konqueror","konqueror"); newButton(node,"kcalc","kcalc"); newButton(node,"gimp","gimp"); newButton(node,"kfm_home","kfmclient openProfile filemanagement"); node = newMenu(node,QString::null,"kmix"); newButton(node,"kmix","kmix"); newButton(node,"k3b","k3b"); newButton(node,"amarok","amarok"); newButton(node,"kaffeine","kaffeine"); } Menu * Config::menuFromXML( const QDomElement & ownNode, Kommando * buttonParent, Menu* parent) { QDomNode node=ownNode.firstChild(); Menu* newMenu = new Menu(parent,ownNode.attribute("appname")); while(!node.isNull()){ if(node.isElement()){ RoundButton* button; if(node.nodeName() == "button"){ button = comButtonFromXML(node.toElement(),buttonParent); newMenu->insert(button); } else if(node.nodeName()=="menu"){ Menu* subMenu = menuFromXML(node.toElement(),buttonParent,newMenu); //establish all necessary connections, e.g. menu structure button = new SubmenuButton(buttonParent,subMenu,mMenuButtonSize); newMenu->insert(button); button->setIcon(subMenu->IconPath()); } else if(node.nodeName()=="icon"){ newMenu->setIconPath(node.firstChild().nodeValue()); } } node=node.nextSibling(); } newMenu->hideButtons(); return newMenu; } CommandoButton* Config::comButtonFromXML(const QDomElement& ownNode, Kommando* parent) { CommandoButton* button = new CommandoButton(parent,mMenuButtonSize); QDomNode bnode=ownNode.firstChild(); while (!bnode.isNull()){ if(bnode.nodeName() == "command"){ button->setCommand(bnode.firstChild().nodeValue()); } else if (bnode.nodeName() == "icon"){ button->setIcon(bnode.firstChild().nodeValue()); } bnode=bnode.nextSibling(); } return button; } QDomElement Config::newNode( const QString& nodename, QDomNode& parent, int value ) { QDomElement node=doc->createElement(nodename); node.appendChild(doc->createTextNode(QString::number(value))); parent.appendChild(node); return node; } QDomElement Config::newNode( const QString& nodename, QDomNode& parent, float value ) { QDomElement node=doc->createElement(nodename); node.appendChild(doc->createTextNode(QString::number(value))); parent.appendChild(node); return node; } QDomElement Config::newNode( const QString& nodename, QDomNode& parent, const QString& value ) { QDomElement node=doc->createElement(nodename); node.appendChild(doc->createTextNode(value)); parent.appendChild(node); return node; } QDomElement Config::newNode( const QString& nodename, QDomNode& parent, const QString& value, const QString& attrname, const QString& attrvalue ) { QDomElement node=doc->createElement(nodename); node.setAttribute(attrname,attrvalue); node.appendChild(doc->createTextNode(value)); parent.appendChild(node); return node; } QDomElement Config::newButton(QDomNode& parent, const QString& icon, const QString& command ) { QDomElement root = doc->createElement("button"); if(command!=""){ QDomElement node = doc->createElement("command"); node.appendChild(doc->createTextNode(command)); root.appendChild(node); } if(icon!=""){ QDomElement node=doc->createElement("icon"); node.appendChild(doc->createTextNode(icon)); root.appendChild(node); } parent.appendChild(root); return root; } QDomElement Config::newMenu( QDomNode & parent, const QString& appName, const QString& icon ) { QDomElement root = doc->createElement("menu"); if(appName != QString::null){ root.setAttribute("appname", appName); } if(icon != QString::null){ QDomElement node=doc->createElement("icon"); node.appendChild(doc->createTextNode(icon)); root.appendChild(node); } parent.appendChild(root); return root; } void Config::menuItemToXML( QDomNode & parent, MenuListViewItem* item) { if(item->type()==MenuListViewItem::Menu){ QDomElement node = newMenu(parent,QString::null,item->iconPath()); QListViewItem* temp = item->firstChild(); while(temp){ menuItemToXML(node,static_cast(temp)); temp=temp->nextSibling(); } } else if(item->type()==MenuListViewItem::Button){ newButton(parent,item->iconPath(),item->text(1)); } } void Config::menuItemFromXML(KommandoView* parent, QListViewItem* after, const QDomElement& ownNode) { MenuListViewItem* item; if (ownNode.tagName()=="menu"){ item = new MenuListViewItem(parent,after,"Menu",MenuListViewItem::Menu); item->setOpen(true); } else if (ownNode.tagName()=="button"){ item = new MenuListViewItem(parent,after,"Button",MenuListViewItem::Button); } else return; itemHelper(ownNode,item); //Parse properties and children of this item } void Config::menuItemFromXML(QListViewItem* parent, QListViewItem* after, const QDomElement& ownNode) { MenuListViewItem* item; if (ownNode.tagName()=="menu"){ item = new MenuListViewItem(parent,after,"Menu",MenuListViewItem::Menu); item->setOpen(true); } else if (ownNode.tagName()=="button"){ item = new MenuListViewItem(parent,after,"Button",MenuListViewItem::Button); } else return; itemHelper(ownNode,item); //Parse properties and children of this item } void Config::itemHelper(const QDomElement& ownNode, MenuListViewItem* item) { QDomNode temp = ownNode.firstChild(); while(!temp.isNull()){ if(temp.isElement()){ QDomElement temp2=temp.toElement(); if(temp2.tagName() == "icon"){ item->setIconPath(temp2.firstChild().nodeValue()); } else if((temp2.tagName() == "command") && (item->type() == MenuListViewItem::Button)){ item->setText(1,temp2.firstChild().nodeValue()); //is item a menu? otherwise parsing buttons and submenus would not make sense } else if(((temp2.tagName() == "menu") || (temp2.tagName() == "button")) && (item->type() == MenuListViewItem::Menu)){ menuItemFromXML(item,item->lastChild(),temp2); } } temp=temp.nextSibling(); } }