Commit 37088799 authored by Robert Knight's avatar Robert Knight
Browse files

* Update the regular expression for the Url filter.  Anything in the form
  letters://any-non-whitespace-characters is treated as a Url

* Correct the test which compares the old and new values and ranges when
  updating the terminal display's scroll bar.  
  This fixes the scroll bar being repainted unnecessarily often.  Found
  with the nifty QT_FLUSH_PAINT debugging tool.

* Select the profile name (set to "New Profile" by default) and focus the 
  profile name edit area when showing the Edit Profile dialog for a new
  profile to allow the user to easily set the name.

* Always use color scheme list animation, not just when the Edit Profile 
  dialog is first displayed as per richmoore's suggestion. 

* Update Edit Profile dialog caption when profile name is changed.

* Update favorite status icon in Manage Profiles dialog when the favorite
  status is changed by another object.

* Add disabled menu item which is shown in the 'Change Profile' list
  when there are no other profiles there

svn path=/trunk/KDE/kdebase/apps/konsole/; revision=683787
parent 0527ef66
......@@ -57,6 +57,7 @@ using namespace Konsole;
EditProfileDialog::EditProfileDialog(QWidget* parent)
: KDialog(parent)
, _colorSchemeAnimationTimeLine(0)
{
setCaption(i18n("Edit Profile"));
setButtons( KDialog::Ok | KDialog::Cancel | KDialog::Apply | KDialog::Default );
......@@ -78,7 +79,7 @@ EditProfileDialog::EditProfileDialog(QWidget* parent)
// to be refreshed when the user switches to them
_pageNeedsUpdate.resize( _ui->tabWidget->count() );
connect( _ui->tabWidget , SIGNAL(currentChanged(int)) , this ,
SLOT(ensurePageLoaded(int)) );
SLOT(preparePage(int)) );
_tempProfile = new Profile;
......@@ -116,6 +117,10 @@ void EditProfileDialog::accept()
unpreviewAll();
KDialog::accept();
}
void EditProfileDialog::updateCaption(const QString& profileName)
{
setCaption( i18n("Edit Profile \"%1\"",profileName) );
}
void EditProfileDialog::setProfile(const QString& key)
{
_profileKey = key;
......@@ -125,14 +130,14 @@ void EditProfileDialog::setProfile(const QString& key)
Q_ASSERT( info );
// update caption
setCaption( i18n("Edit Profile \"%1\"",info->name()) );
updateCaption(info->name());
// mark each page of the dialog as out of date
// and force an update of the currently visible page
//
// the other pages will be updated as necessary
_pageNeedsUpdate.fill(true);
ensurePageLoaded( _ui->tabWidget->currentIndex() );
preparePage( _ui->tabWidget->currentIndex() );
if ( _tempProfile )
{
......@@ -144,17 +149,17 @@ const Profile* EditProfileDialog::lookupProfile() const
{
return SessionManager::instance()->profile(_profileKey);
}
void EditProfileDialog::ensurePageLoaded(int page)
void EditProfileDialog::preparePage(int page)
{
const Profile* info = lookupProfile();
Q_ASSERT( _pageNeedsUpdate.count() > page );
Q_ASSERT( info );
QWidget* pageWidget = _ui->tabWidget->widget(page);
if ( _pageNeedsUpdate[page] )
{
QWidget* pageWidget = _ui->tabWidget->widget(page);
if ( pageWidget == _ui->generalTab )
setupGeneralPage(info);
else if ( pageWidget == _ui->tabsTab )
......@@ -172,6 +177,15 @@ void EditProfileDialog::ensurePageLoaded(int page)
_pageNeedsUpdate[page] = false;
}
// start page entry animation for color schemes
if ( pageWidget == _ui->appearanceTab )
_colorSchemeAnimationTimeLine->start();
}
void EditProfileDialog::selectProfileName()
{
_ui->profileNameEdit->selectAll();
_ui->profileNameEdit->setFocus();
}
void EditProfileDialog::setupGeneralPage(const Profile* info)
{
......@@ -324,6 +338,7 @@ void EditProfileDialog::selectIcon()
void EditProfileDialog::profileNameChanged(const QString& text)
{
_tempProfile->setProperty(Profile::Name,text);
updateCaption(_tempProfile->name());
}
void EditProfileDialog::initialDirChanged(const QString& dir)
{
......@@ -354,10 +369,10 @@ void EditProfileDialog::setupAppearancePage(const Profile* info)
ColorSchemeViewDelegate* delegate = new ColorSchemeViewDelegate(this);
QTimeLine* timeLine = new QTimeLine( 500 , this );
delegate->setEntryTimeLine(timeLine);
_colorSchemeAnimationTimeLine = new QTimeLine( 500 , this );
delegate->setEntryTimeLine(_colorSchemeAnimationTimeLine);
connect( timeLine , SIGNAL(valueChanged(qreal)) , this ,
connect( _colorSchemeAnimationTimeLine , SIGNAL(valueChanged(qreal)) , this ,
SLOT(colorSchemeAnimationUpdate()) );
_ui->colorSchemeList->setItemDelegate(delegate);
......@@ -387,9 +402,6 @@ void EditProfileDialog::setupAppearancePage(const Profile* info)
SLOT(setFontSize(int)) );
connect( _ui->editFontButton , SIGNAL(clicked()) , this ,
SLOT(showFontDialog()) );
// start entry animation
timeLine->start();
}
void EditProfileDialog::colorSchemeAnimationUpdate()
{
......
......@@ -79,6 +79,14 @@ public:
*/
void setProfile(const QString& key);
/**
* Selects the text in the profile name edit area.
* When the dialog is being used to create a new profile,
* this can be used to draw the user's attention to the profile name
* and make it easy for them to change it.
*/
void selectProfileName();
public slots:
// reimplemented
virtual void accept();
......@@ -90,7 +98,7 @@ protected:
private slots:
// sets up the specified tab page if necessary
void ensurePageLoaded(int);
void preparePage(int);
// saves changes to profile
void save();
......@@ -178,6 +186,8 @@ private:
void unpreview(int property);
void unpreviewAll();
void updateCaption(const QString& profileName);
struct RadioOption
{
QAbstractButton* button;
......@@ -205,6 +215,8 @@ private:
// after an update by a call to ensurePageLoaded()
QVector<bool> _pageNeedsUpdate;
QHash<int,QVariant> _previewedProperties;
QTimeLine* _colorSchemeAnimationTimeLine;
};
/**
......
......@@ -488,7 +488,7 @@ void UrlFilter::HotSpot::activate(QObject* object)
//regexp matches:
// full url:
// protocolname:// or www. followed by numbers, letters dots and dashes or the '@' character.
const QRegExp UrlFilter::FullUrlRegExp("([a-z]+://|www\\.)[a-zA-Z0-9@\\-\\./]+");
const QRegExp UrlFilter::FullUrlRegExp("([a-z]+://|www\\.)[^\\s]+");
// email address:
// [word chars, dots or dashes]@[word chars, dots or dashes].[word chars]
const QRegExp UrlFilter::EmailAddressRegExp("(\\w|\\.|-)+@(\\w|\\.|-)+\\.\\w+");
......
......@@ -47,7 +47,7 @@ ManageProfilesDialog::ManageProfilesDialog(QWidget* parent)
// hide vertical header
_ui->sessionTable->verticalHeader()->hide();
_ui->sessionTable->setItemDelegateForColumn(1,new ProfileItemDelegate(this));
_ui->sessionTable->setItemDelegateForColumn(FavoriteStatusColumn,new ProfileItemDelegate(this));
// update table and listen for changes to the session types
updateTableModel();
......@@ -57,6 +57,9 @@ ManageProfilesDialog::ManageProfilesDialog(QWidget* parent)
SLOT(updateTableModel()) );
connect( SessionManager::instance() , SIGNAL(profileChanged(const QString&)) , this,
SLOT(updateTableModel()) );
connect( SessionManager::instance() ,
SIGNAL(favoriteStatusChanged(const QString&,bool)) , this ,
SLOT(updateFavoriteStatus(const QString&,bool)) );
// resize the session table to the full width of the table
_ui->sessionTable->horizontalHeader()->setHighlightSections(false);
......@@ -106,7 +109,7 @@ void ManageProfilesDialog::itemDataChanged(QStandardItem* item)
qDebug() << "New key sequence: " << item->text();
SessionManager::instance()->setShortcut(item->data(Qt::UserRole+1).value<QString>(),
SessionManager::instance()->setShortcut(item->data(ShortcutRole).value<QString>(),
sequence);
}
}
......@@ -137,7 +140,7 @@ void ManageProfilesDialog::updateTableModel()
if ( !info->icon().isEmpty() )
item->setIcon( KIcon(info->icon()) );
item->setData(key);
item->setData(key,ProfileKeyRole);
const bool isFavorite = SessionManager::instance()->findFavorites().contains(key);
......@@ -148,14 +151,14 @@ void ManageProfilesDialog::updateTableModel()
else
favoriteItem->setData(KIcon(),Qt::DecorationRole);
favoriteItem->setData(key,Qt::UserRole+1);
favoriteItem->setData(key,ProfileKeyRole);
// shortcut column
QStandardItem* shortcutItem = new QStandardItem();
QString shortcut = SessionManager::instance()->shortcut(key).
toString();
shortcutItem->setText(shortcut);
shortcutItem->setData(key,Qt::UserRole+1);
shortcutItem->setData(key,ShortcutRole);
itemList << item << favoriteItem << shortcutItem;
......@@ -246,11 +249,16 @@ void ManageProfilesDialog::newType()
newProfile->setProperty(Profile::Name,i18n("New Profile"));
const QString& key = SessionManager::instance()->addProfile(newProfile);
dialog.setProfile(key);
dialog.selectProfileName();
// if the user doesn't accept the dialog, remove the temporary profile
// if they do accept the dialog, it will become a permanent profile
if ( dialog.exec() != QDialog::Accepted )
SessionManager::instance()->deleteProfile(key);
else
{
SessionManager::instance()->setFavorite(key,true);
}
}
void ManageProfilesDialog::editSelected()
{
......@@ -268,6 +276,21 @@ QString ManageProfilesDialog::selectedKey() const
selectionModel()->
selectedIndexes().first().data( Qt::UserRole + 1 ).value<QString>();
}
void ManageProfilesDialog::updateFavoriteStatus(const QString& key , bool favorite)
{
Q_ASSERT( _sessionModel );
const QModelIndex topIndex = _sessionModel->index(0,FavoriteStatusColumn);
QModelIndexList list = _sessionModel->match( topIndex , ProfileKeyRole,
key );
foreach( QModelIndex index , list )
{
const KIcon icon = favorite ? KIcon("favorites") : KIcon();
_sessionModel->setData(index,icon,Qt::DecorationRole);
}
}
ProfileItemDelegate::ProfileItemDelegate(QObject* parent)
: QItemDelegate(parent)
......@@ -278,16 +301,11 @@ bool ProfileItemDelegate::editorEvent(QEvent* event,QAbstractItemModel* model,
{
if ( event->type() == QEvent::MouseButtonPress || event->type() == QEvent::KeyPress )
{
const QString& key = index.data(Qt::UserRole + 1).value<QString>();
const QString& key = index.data(ManageProfilesDialog::ProfileKeyRole).value<QString>();
const bool isFavorite = !SessionManager::instance()->findFavorites().contains(key);
SessionManager::instance()->setFavorite(key,
isFavorite);
if ( isFavorite )
model->setData(index,KIcon("favorites"),Qt::DecorationRole);
else
model->setData(index,KIcon(),Qt::DecorationRole);
}
return true;
......
......@@ -48,11 +48,14 @@ class ManageProfilesDialog : public KDialog
{
Q_OBJECT
friend class ProfileItemDelegate;
public:
/** Constructs a new profile type with the specified parent. */
ManageProfilesDialog(QWidget* parent = 0);
virtual ~ManageProfilesDialog();
protected:
virtual void showEvent(QShowEvent* event);
......@@ -72,6 +75,8 @@ private slots:
// session manager
void updateTableModel();
void updateFavoriteStatus(const QString& key , bool favorite);
private:
QString selectedKey() const; // return the key associated with the currently selected
// item in the profile table
......@@ -80,6 +85,10 @@ private:
// their default / non-default profile status
Ui::ManageProfilesDialog* _ui;
QStandardItemModel* _sessionModel;
static const int FavoriteStatusColumn = 1;
static const int ProfileKeyRole = Qt::UserRole + 1;
static const int ShortcutRole = Qt::UserRole + 1;
};
class ProfileItemDelegate : public QItemDelegate
......
......@@ -65,6 +65,8 @@ QString ProcessInfo::format(const QString& input) const
// search for and replace known markers
output.replace("%u","NOT IMPLEMENTED YET");
output.replace("%n",name(&ok));
output.replace("%c",formatCommand(name(&ok),arguments(&ok),ShortCommandFormat));
output.replace("%C",formatCommand(name(&ok),arguments(&ok),LongCommandFormat));
output.replace("%D",currentDir(&ok));
output.replace("%d",formatShortDir(currentDir(&ok)));
......@@ -80,6 +82,13 @@ const char* ProcessInfo::DefaultCommonDirNames[] =
"share" , "examples" , "icons" ,
"pics" , "plugins" , 0 };
QString ProcessInfo::formatCommand(const QString& name,
const QVector<QString>& arguments,
CommandFormat format) const
{
// TODO Implement me
return QStringList(QList<QString>::fromVector(arguments)).join(" ");
}
QString ProcessInfo::formatShortDir(const QString& input) const
{
QString result;
......
......@@ -237,6 +237,15 @@ private:
// space-constrained UI elements (eg. tabs)
QString formatShortDir(const QString& dirPath) const;
enum CommandFormat
{
ShortCommandFormat,
LongCommandFormat
};
// takes a process name and its arguments and produces formatted output
QString formatCommand(const QString& name , const QVector<QString>& arguments ,
CommandFormat format) const;
// valid bits for _fields variable, ensure that
// _fields is changed to an int if more than 8 fields are added
enum FIELD_BITS
......
......@@ -27,6 +27,7 @@
// KDE
#include <KIcon>
#include <KLocalizedString>
// Konsole
#include "SessionManager.h"
......@@ -36,11 +37,17 @@ using namespace Konsole;
ProfileList::ProfileList(bool addShortcuts , QObject* parent)
: QObject(parent)
, _addShortcuts(addShortcuts)
, _emptyListAction(0)
{
SessionManager* manager = SessionManager::instance();
// construct the list of favorite session types
_group = new QActionGroup(this);
// disabled action to be shown only when the list is empty
_emptyListAction = new QAction(i18n("No profiles available"),_group);
_emptyListAction->setEnabled(false);
QList<QString> list = manager->findFavorites().toList();
qSort(list);
......@@ -54,13 +61,25 @@ ProfileList::ProfileList(bool addShortcuts , QObject* parent)
connect( _group , SIGNAL(triggered(QAction*)) , this , SLOT(triggered(QAction*)) );
// listen for future changes to the session list
connect( manager , SIGNAL(favoriteStatusChanged(const QString&,bool)) , this ,
SLOT(favoriteChanged(const QString&,bool)) );
connect( manager , SIGNAL(profileChanged(const QString&)) , this ,
SLOT(profileChanged(const QString&)) );
}
void ProfileList::updateEmptyAction()
{
Q_ASSERT( _group );
Q_ASSERT( _emptyListAction );
// show empty list action when it is the only action
// in the group
const bool showEmptyAction = _group->actions().count() == 1;
if ( showEmptyAction != _emptyListAction->isVisible() )
_emptyListAction->setVisible(showEmptyAction);
}
QAction* ProfileList::actionForKey(const QString& key) const
{
QListIterator<QAction*> iter(_group->actions());
......@@ -119,6 +138,8 @@ void ProfileList::favoriteChanged(const QString& key,bool isFavorite)
emit actionsChanged(_group->actions());
}
}
updateEmptyAction();
}
void ProfileList::triggered(QAction* action)
......
......@@ -84,9 +84,13 @@ private slots:
private:
QAction* actionForKey(const QString& key) const;
void updateAction(QAction* action , Profile* profile);
void updateEmptyAction();
QActionGroup* _group;
bool _addShortcuts;
// action to show when the list is empty
QAction* _emptyListAction;
};
}
......
......@@ -1470,8 +1470,8 @@ void TerminalDisplay::setScroll(int cursor, int slines)
//
// setting the range or value of a _scrollBar will always trigger
// a repaint, so it should be avoided if it is not necessary
if ( _scrollBar->minimum() == 0 &&
_scrollBar->maximum() == slines &&
if ( _scrollBar->minimum() == 0 &&
_scrollBar->maximum() == (slines - _lines) &&
_scrollBar->value() == cursor )
{
//qDebug() << "no change in _scrollBar - skipping update";
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment