Logo Search packages:      
Sourcecode: kdebase-kde4 version File versions  Download package

Profile.cpp

/*
    This source file is part of Konsole, a terminal emulator.

    Copyright (C) 2006-7 by Robert Knight <robertknight@gmail.com>

    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., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301  USA.
*/

// Own
#include "Profile.h"

// Qt
#include <QtCore/QFile>
#include <QtCore/QFileInfo>
#include <QtCore/QTextCodec>

// KDE
#include <KConfigGroup>
#include <KDesktopFile>
#include <KGlobal>
#include <KGlobalSettings>
#include <KLocale>
#include <KDebug>
#include <KStandardDirs>

// System
#include <unistd.h>

// Konsole
#include "ShellCommand.h"

using namespace Konsole;

// mappings between property enum values and names
//
// multiple names are defined for some property values,
// in these cases, the "proper" string name comes first,
// as that is used when reading/writing profiles from/to disk
//
// the other names are usually shorter versions for convenience
// when parsing konsoleprofile commands
const Profile::PropertyNamePair Profile::DefaultPropertyNames[] =
{
      { Path , "Path" }
    , { Name , "Name" }
    , { Title , "Title" }
    , { Icon , "Icon" }
    , { Command , "Command" }
    , { Arguments , "Arguments" }
    , { Environment , "Environment" }
    , { Directory , "Directory" }

    , { LocalTabTitleFormat , "LocalTabTitleFormat" }
    , { LocalTabTitleFormat , "tabtitle"}
    
    , { RemoteTabTitleFormat , "RemoteTabTitleFormat" }
    , { ShowMenuBar , "ShowMenuBar" }
    , { TabBarMode , "TabBarMode" }
    , { Font , "Font" }

    , { ColorScheme , "ColorScheme" }
    , { ColorScheme , "colors" }
    
    , { KeyBindings , "KeyBindings" }
    , { HistoryMode , "HistoryMode" }
    , { HistorySize , "HistorySize" } 
    , { ScrollBarPosition , "ScrollBarPosition" }
    , { BlinkingTextEnabled , "BlinkingTextEnabled" }
    , { FlowControlEnabled , "FlowControlEnabled" }
    , { AllowProgramsToResizeWindow , "AllowProgramsToResizeWindow" }
    , { BlinkingCursorEnabled , "BlinkingCursorEnabled" }
    , { UseCustomCursorColor , "UseCustomCursorColor" }
    , { CursorShape , "CursorShape" }
    , { CustomCursorColor , "CustomCursorColor" }
    , { WordCharacters , "WordCharacters" }
    , { TabBarPosition , "TabBarPosition" }
    , { DefaultEncoding , "DefaultEncoding" }
    , { AntiAliasFonts, "AntiAliasFonts" }
    , { (Property)0 , 0 }
};

QHash<QString,Profile::Property> Profile::_propertyByName;
QHash<Profile::Property,QString> Profile::_nameByProperty;

void Profile::fillTableWithDefaultNames()
{
    static bool filledDefaults = false;

    if ( filledDefaults )
        return;

    const PropertyNamePair* iter = DefaultPropertyNames;
    while ( iter->name != 0 )
    {
       registerName(iter->property,iter->name);
       iter++;
    }

   filledDefaults = true; 
}

FallbackProfile::FallbackProfile()
 : Profile(0)
{
    // Fallback settings
    setProperty(Name,i18n("Shell"));
    setProperty(Command,getenv("SHELL"));
    setProperty(Icon,"utilities-terminal");
    setProperty(Arguments,QStringList() << getenv("SHELL"));
    setProperty(Environment,QStringList() << "TERM=xterm");
    setProperty(LocalTabTitleFormat,"%d : %n");
    setProperty(RemoteTabTitleFormat,"%H (%u)");
    setProperty(TabBarMode,AlwaysShowTabBar);
    setProperty(TabBarPosition,TabBarBottom);
    setProperty(ShowMenuBar,true);


    setProperty(KeyBindings,"default");
    setProperty(ColorScheme,"Linux");
    setProperty(Font,KGlobalSettings::fixedFont());

    setProperty(HistoryMode,FixedSizeHistory);
    setProperty(HistorySize,1000);
    setProperty(ScrollBarPosition,ScrollBarRight);
    
    setProperty(FlowControlEnabled,true);
    setProperty(AllowProgramsToResizeWindow,true);
    setProperty(BlinkingTextEnabled,true);
    
    setProperty(BlinkingCursorEnabled,false);
    setProperty(CursorShape,BlockCursor);
    setProperty(UseCustomCursorColor,false);
    setProperty(CustomCursorColor,Qt::black);

    setProperty(DefaultEncoding,QString(QTextCodec::codecForLocale()->name()));
    setProperty(AntiAliasFonts,true);

    // default taken from KDE 3
    setProperty(WordCharacters,":@-./_~?&=%+#");

    // Fallback should not be shown in menus
    setHidden(true);
}

00158 Profile::Profile(Profile* parent)
    : _parent(parent)
     ,_hidden(false)
{
}

00164 bool Profile::isHidden() const { return _hidden; }
00165 void Profile::setHidden(bool hidden) { _hidden = hidden; }

00167 void Profile::setParent(Profile* parent) { _parent = parent; }
00168 const Profile* Profile::parent() const { return _parent; }

00170 bool Profile::isEmpty() const
{
    return _propertyValues.isEmpty();
}
00174 QHash<Profile::Property,QVariant> Profile::setProperties() const
{
    return _propertyValues;
}

00179 QVariant Profile::property(Property property) const
{
      bool canInheritProperty = property != Path;

    if ( _propertyValues.contains(property) )
        return _propertyValues[property];
    else if ( _parent && canInheritProperty )
        return _parent->property(property);
    else
        return QVariant();
}
00190 void Profile::setProperty(Property property , const QVariant& value)
{
    _propertyValues.insert(property,value);
}
00194 bool Profile::isPropertySet(Property property) const
{
    return _propertyValues.contains(property);
}

00199 bool Profile::isNameRegistered(const QString& name) 
{
    // insert default names into table the first time this is called
    fillTableWithDefaultNames();

    return _propertyByName.contains(name);
}

00207 Profile::Property Profile::lookupByName(const QString& name)
{
    // insert default names into table the first time this is called
    fillTableWithDefaultNames();

    return _propertyByName[name.toLower()];
}
00214 QString Profile::primaryNameForProperty(Property property)
{
    // insert default names into table the first time this is called
    fillTableWithDefaultNames();

    return _nameByProperty[property];
}
00221 QList<QString> Profile::namesForProperty(Property property)
{
    // insert default names into table the first time this is called
    fillTableWithDefaultNames();

    return QList<QString>() << primaryNameForProperty(property);
}
00228 void Profile::registerName(Property property , const QString& name)
{
    _propertyByName.insert(name.toLower(),property);

    // only allow one property -> name map
    // (multiple name -> property mappings are allowed though)
    if ( !_nameByProperty.contains(property) )
        _nameByProperty.insert(property,name);
}

00238 QString KDE4ProfileWriter::getPath(const Profile* info)
{
    QString newPath;

    if ( info->isPropertySet(Profile::Path) && 
         info->path().startsWith(KGlobal::dirs()->saveLocation("data", "konsole/")) )
    {
        newPath = info->path();
    }
    else
    {
        // use the profile name + ".profile" and save it in $KDEHOME
        newPath = KGlobal::dirs()->saveLocation("data","konsole/") + info->name() + ".profile";
    }

    kDebug(1211) << "Saving profile under name: " << newPath;

    return newPath;
}
void KDE4ProfileWriter::writeStandardElement(KConfigGroup& group ,  const Profile* profile ,
                                             Profile::Property attribute)
{
    QString name = Profile::primaryNameForProperty(attribute);
    
    if ( profile->isPropertySet(attribute) )
        group.writeEntry(name,profile->property(attribute));
}
00265 bool KDE4ProfileWriter::writeProfile(const QString& path , const Profile* profile)
{
    KConfig config(path,KConfig::NoGlobals);

    // Basic Profile Settings
    KConfigGroup general = config.group("General");

    // Parent profile if set, when loading the profile in future, the parent
    // must be loaded as well if it exists.
    if ( profile->parent() != 0 )
        general.writeEntry("Parent",profile->parent()->path());

    if ( profile->isPropertySet(Profile::Name) )
        general.writeEntry("Name",profile->name());
    
    if (    profile->isPropertySet(Profile::Command) 
         || profile->isPropertySet(Profile::Arguments) )
        general.writeEntry("Command",
                ShellCommand(profile->command(),profile->arguments()).fullCommand());

    if ( profile->isPropertySet(Profile::Directory) )
        general.writeEntry("Directory",profile->defaultWorkingDirectory());

    writeStandardElement( general ,  profile , Profile::Environment );
    writeStandardElement( general ,  profile , Profile::Icon );
    
    // Tab Titles
    writeStandardElement( general ,  profile , Profile::LocalTabTitleFormat );
    writeStandardElement( general ,  profile , Profile::RemoteTabTitleFormat );

    // Menu and Tab Bar
    writeStandardElement( general ,  profile , Profile::TabBarMode );
    writeStandardElement( general ,  profile , Profile::TabBarPosition );
    writeStandardElement( general ,  profile , Profile::ShowMenuBar );

    // Keyboard
    KConfigGroup keyboard = config.group("Keyboard");
    writeStandardElement( keyboard , profile , Profile::KeyBindings );

    // Appearance
    KConfigGroup appearance = config.group("Appearance");

    writeStandardElement( appearance , profile , Profile::ColorScheme );
    writeStandardElement( appearance , profile , Profile::Font );
    writeStandardElement( appearance , profile , Profile::AntiAliasFonts );
   
    // Scrolling
    KConfigGroup scrolling = config.group("Scrolling");

    writeStandardElement( scrolling ,  profile , Profile::HistoryMode );
    writeStandardElement( scrolling ,  profile , Profile::HistorySize );
    writeStandardElement( scrolling ,  profile , Profile::ScrollBarPosition ); 

    // Terminal Features
    KConfigGroup terminalFeatures = config.group("Terminal Features");

    writeStandardElement( terminalFeatures ,  profile , Profile::FlowControlEnabled );
    writeStandardElement( terminalFeatures ,  profile , Profile::BlinkingCursorEnabled );

    // Cursor 
    KConfigGroup cursorOptions = config.group("Cursor Options");

    writeStandardElement( cursorOptions ,  profile , Profile::UseCustomCursorColor );
    writeStandardElement( cursorOptions ,  profile , Profile::CustomCursorColor );
    writeStandardElement( cursorOptions ,  profile , Profile::CursorShape );

    // Interaction
    KConfigGroup interactionOptions = config.group("Interaction Options");

    writeStandardElement( interactionOptions ,  profile , Profile::WordCharacters );

    // Encoding
    KConfigGroup encodingOptions = config.group("Encoding Options");
    writeStandardElement( encodingOptions ,  profile , Profile::DefaultEncoding );

    return true;
}

00343 QStringList KDE4ProfileReader::findProfiles()
{
    return KGlobal::dirs()->findAllResources("data","konsole/*.profile",
            KStandardDirs::NoDuplicates);
}
00348 bool KDE4ProfileReader::readProfile(const QString& path , Profile* profile , QString& parentProfile)
{
    //kDebug() << "KDE 4 Profile Reader:" << path;

    KConfig config(path,KConfig::NoGlobals);

    // general
    KConfigGroup general = config.group("General");

    if ( general.hasKey("Parent") )
        parentProfile = general.readEntry("Parent");

    if ( general.hasKey("Name") )
        profile->setProperty(Profile::Name,general.readEntry("Name"));
    else
        return false;

    if ( general.hasKey("Command") )
    {
        ShellCommand shellCommand(general.readEntry("Command"));

        profile->setProperty(Profile::Command,shellCommand.command());
        profile->setProperty(Profile::Arguments,shellCommand.arguments());
    }

    readStandardElement<QString>(general,profile,Profile::Directory);
    readStandardElement<QStringList>(general,profile,Profile::Environment);
    readStandardElement<QString>(general,profile,Profile::Icon);
    readStandardElement<QString>(general,profile,Profile::LocalTabTitleFormat); 
    readStandardElement<QString>(general,profile,Profile::RemoteTabTitleFormat);
   
    readStandardElement<int>(general,profile,Profile::TabBarMode);
    readStandardElement<int>(general,profile,Profile::TabBarPosition);
    readStandardElement<bool>(general,profile,Profile::ShowMenuBar);

    // keyboard
    KConfigGroup keyboard = config.group("Keyboard");
    readStandardElement<QString>(keyboard,profile,Profile::KeyBindings);

    // appearance
    KConfigGroup appearance = config.group("Appearance");

    readStandardElement<QString>(appearance,profile,Profile::ColorScheme);
    readStandardElement<QFont>(appearance,profile,Profile::Font);
    readStandardElement<bool>(appearance,profile,Profile::AntiAliasFonts);

    // scrolling
    KConfigGroup scrolling = config.group("Scrolling");

    readStandardElement<int>(scrolling,profile,Profile::HistoryMode);
    readStandardElement<int>(scrolling,profile,Profile::HistorySize);
    readStandardElement<int>(scrolling,profile,Profile::ScrollBarPosition);

    // terminal features
    KConfigGroup terminalFeatures = config.group("Terminal Features");

    readStandardElement<bool>(terminalFeatures,profile,Profile::FlowControlEnabled);
    readStandardElement<bool>(terminalFeatures,profile,Profile::BlinkingCursorEnabled);

    // cursor settings
    KConfigGroup cursorOptions = config.group("Cursor Options");

    readStandardElement<bool>(cursorOptions,profile,Profile::UseCustomCursorColor);
    readStandardElement<QColor>(cursorOptions,profile,Profile::CustomCursorColor);
    readStandardElement<int>(cursorOptions,profile,Profile::CursorShape);

    // interaction options
    KConfigGroup interactionOptions = config.group("Interaction Options");
    
    readStandardElement<QString>(interactionOptions,profile,Profile::WordCharacters);

    // encoding
    KConfigGroup encodingOptions = config.group("Encoding Options");
    readStandardElement<QString>(encodingOptions,profile,Profile::DefaultEncoding);

    return true;
}
template <typename T>
void KDE4ProfileReader::readStandardElement(const KConfigGroup& group , 
                                            Profile* info , 
                                            Profile::Property property)
{
    QString name = Profile::primaryNameForProperty(property);

    if ( group.hasKey(name) )
        info->setProperty(property,group.readEntry(name,T()));
}
                                                    
00436 QStringList KDE3ProfileReader::findProfiles()
{
    return KGlobal::dirs()->findAllResources("data", "konsole/*.desktop", 
            KStandardDirs::NoDuplicates);
}
00441 bool KDE3ProfileReader::readProfile(const QString& path , Profile* profile , QString& parentProfile)
{
    if (!QFile::exists(path))
        return false;

    // KDE 3 profiles do not have parents
    parentProfile = QString();

    KDesktopFile* desktopFile = new KDesktopFile(path);
    KConfigGroup* config = new KConfigGroup( desktopFile->desktopGroup() );

    if ( config->hasKey("Name") )
        profile->setProperty(Profile::Name,config->readEntry("Name"));

    kDebug() << "reading KDE 3 profile " << profile->name();

    if ( config->hasKey("Icon") )
        profile->setProperty(Profile::Icon,config->readEntry("Icon"));
    if ( config->hasKey("Exec") )
    {
        const QString& fullCommand = config->readEntry("Exec");
        ShellCommand shellCommand(fullCommand);
    
        profile->setProperty(Profile::Command,shellCommand.command());
        profile->setProperty(Profile::Arguments,shellCommand.arguments());
    }
    if ( config->hasKey("Schema") )
    {
        profile->setProperty(Profile::ColorScheme,config->readEntry("Schema").replace
                                            (".schema",QString()));        
    }
    if ( config->hasKey("defaultfont") )
    {
        profile->setProperty(Profile::Font,config->readEntry("defaultfont"));
    }
    if ( config->hasKey("KeyTab") )
    {
        profile->setProperty(Profile::KeyBindings,config->readEntry("KeyTab"));
    }
    if ( config->hasKey("Term") )
    {
        profile->setProperty(Profile::Environment,
                QStringList() << "TERM="+config->readEntry("Term"));
    }
    if ( config->hasKey("Cwd") )
    {
        profile->setProperty(Profile::Directory,config->readEntry("Cwd"));
    }

    delete desktopFile;
    delete config;

    return true;
}

00496 QHash<Profile::Property,QVariant> ProfileCommandParser::parse(const QString& input)
{
    QHash<Profile::Property,QVariant> changes;

    // regular expression to parse profile change requests.
    //
    // format: property=value;property=value ...
    //
    // where 'property' is a word consisting only of characters from A-Z
    // where 'value' is any sequence of characters other than a semi-colon
    //
    static QRegExp regExp("([a-zA-Z]+)=([^;]+)");

    int offset = 0;
    while ( regExp.indexIn(input,offset) != -1 )
    {
        if ( regExp.capturedTexts().count() == 3 )
        {
            Profile::Property property = Profile::lookupByName(
                                                regExp.capturedTexts()[1]);
            const QString value = regExp.capturedTexts()[2];

            kDebug() << "property:" << property << "value:" << value;

            changes.insert(property,value);
        }

        offset = input.indexOf(';',offset) + 1;
        if ( offset == 0 )
            break;
    }

    return changes;
}


#include "Profile.moc"


Generated by  Doxygen 1.6.0   Back to index