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

* Add icons for various actions

* Uncheck split-view menu action when detaching the view
* Fix deletion of characters in the terminal display image.


svn path=/branches/work/konsole-split-view/; revision=618303
parent 1343a6d7
......@@ -64,8 +64,6 @@ KonsoleBookmarkHandler::KonsoleBookmarkHandler( KMainWindow* konsole, KMenu* men
KBookmarkManager *manager = KBookmarkManager::managerForFile( m_file, "konsole", false);
//TODO: Replace KApp with KonsoleApp::self()
//manager->setEditorOptions(KApp->caption(), false);
manager->setUpdate( true );
if (toplevel) {
......
......@@ -61,23 +61,25 @@ ViewManager* KonsoleMainWindow::viewManager()
void KonsoleMainWindow::setupActions()
{
KActionCollection* collection = actionCollection();
// File Menu
KAction* newTabAction = new KAction( i18n("New &Tab") , actionCollection() , "new-tab" );
KAction* newWindowAction = new KAction( i18n("New &Window") , actionCollection() , "new-window" );
KAction* newTabAction = new KAction( KIcon("openterm") , i18n("New &Tab") , collection , "new-tab" );
KAction* newWindowAction = new KAction( KIcon("window_new") , i18n("New &Window") , collection , "new-window" );
connect( newTabAction , SIGNAL(triggered()) , this , SLOT(newTab()) );
connect( newWindowAction , SIGNAL(triggered()) , this , SLOT(newWindow()) );
KStandardAction::quit( KonsoleApp::self() , SLOT(quit()) , actionCollection() ,"exit");
KStandardAction::quit( KonsoleApp::self() , SLOT(quit()) , collection ,"exit");
// Bookmark Menu
KActionMenu* bookmarkMenu = new KActionMenu(i18n("&Bookmarks"), actionCollection(),"bookmark");
KActionMenu* bookmarkMenu = new KActionMenu(i18n("&Bookmarks"), collection,"bookmark");
new KonsoleBookmarkHandler( this , bookmarkMenu->menu() , true );
// Settings Menu
KStandardAction::configureNotifications( 0 , 0 , actionCollection() , "configure-notifications" );
KStandardAction::keyBindings( this , SLOT(showShortcutsDialog()) , actionCollection() , "configure-shortcuts" );
KStandardAction::preferences( this , SLOT(showPreferencesDialog()) , actionCollection() ,
KStandardAction::configureNotifications( 0 , 0 , collection , "configure-notifications" );
KStandardAction::keyBindings( this , SLOT(showShortcutsDialog()) , collection , "configure-shortcuts" );
KStandardAction::preferences( this , SLOT(showPreferencesDialog()) , collection ,
"configure-application" );
}
......
TODO before merging with /trunk
===============================
== NOTE: This TODO refers to the old Konsole code, before the start of a new front-end
using KonsoleApp and KonsoleMainWindow. Some parts do not apply to the new
front-end
=========================================================================================
- [DONE] Kill views when the associated session dies
- [DONE] Single top-bottom split-view menu action
......
......@@ -37,42 +37,43 @@ bool SessionController::eventFilter(QObject* watched , QEvent* event)
void SessionController::setupActions()
{
KAction* action = 0;
KActionCollection* collection = actionCollection();
setXMLFile("konsoleui.rc");
// Close Session
action = new KAction( i18n("&Close Tab") , actionCollection() , "close-session" );
action = new KAction( KIcon("fileclose"), i18n("&Close Tab") , collection , "close-session" );
connect( action , SIGNAL(triggered()) , this , SLOT(closeSession()) );
// Copy and Paste
action = new KAction( i18n("&Copy") , actionCollection() , "copy" );
action = new KAction( KIcon("editcopy") , i18n("&Copy") , collection , "copy" );
connect( action , SIGNAL(triggered()) , this , SLOT(copy()) );
action = new KAction( i18n("&Paste") , actionCollection() , "paste" );
action = new KAction( KIcon("editpaste") , i18n("&Paste") , collection , "paste" );
connect( action , SIGNAL(triggered()) , this , SLOT(paste()) );
// Clear and Clear+Reset
action = new KAction( i18n("C&lear Display") , actionCollection() , "clear" );
action = new KAction( i18n("C&lear Display") , collection , "clear" );
connect( action , SIGNAL(triggered()) , this , SLOT(clear()) );
action = new KAction( i18n("Clear and Reset") , actionCollection() , "clear-and-reset" );
action = new KAction( i18n("Clear and Reset") , collection , "clear-and-reset" );
connect( action , SIGNAL(triggered()) , this , SLOT(clearAndReset()) );
// History
action = new KAction( i18n("Search History") , actionCollection() , "search-history" );
action = new KAction( KIcon("find") , i18n("Search History") , collection , "search-history" );
connect( action , SIGNAL(triggered()) , this , SLOT(searchHistory()) );
action = new KAction( i18n("Find Next") , actionCollection() , "find-next" );
action = new KAction( KIcon("next") , i18n("Find Next") , collection , "find-next" );
connect( action , SIGNAL(triggered()) , this , SLOT(findNextInHistory()) );
action = new KAction( i18n("Find Previous") , actionCollection() , "find-previous" );
action = new KAction( KIcon("previous") , i18n("Find Previous") , collection , "find-previous" );
connect( action , SIGNAL(triggered()) , this , SLOT(findPreviousInHistory()) );
action = new KAction( i18n("Save History") , actionCollection() , "save-history" );
action = new KAction( i18n("Save History") , collection , "save-history" );
connect( action , SIGNAL(triggered()) , this , SLOT(saveHistory()) );
action = new KAction( i18n("Clear History") , actionCollection() , "clear-history" );
action = new KAction( i18n("Clear History") , collection , "clear-history" );
connect( action , SIGNAL(triggered()) , this , SLOT(clearHistory()) );
}
......
......@@ -59,6 +59,9 @@ public:
/** Reimplemented to watch for events happening to the view */
virtual bool eventFilter(QObject* watched , QEvent* event);
TESession* session() { return _session; }
TEWidget* view() { return _view; }
signals:
/**
* Emitted when the view associated with the controller is focused.
......
......@@ -34,8 +34,9 @@
// Konsole
#include "TESession.h"
#include "TEHistory.h"
#include "SessionManager.h"
#include "schema.h"
SessionInfo::SessionInfo(const QString& path)
{
......@@ -193,6 +194,9 @@ SessionManager::SessionManager()
_defaultSessionType = newType;
}
// load the colour scheme list
_colorSchemeList = new ColorSchemaList();
Q_ASSERT( _types.count() > 0 );
Q_ASSERT( _defaultSessionType != 0 );
}
......@@ -203,6 +207,8 @@ SessionManager::~SessionManager()
while (infoIter.hasNext())
delete infoIter.next();
delete _colorSchemeList;
}
const QList<TESession*> SessionManager::sessions()
......@@ -248,7 +254,11 @@ TESession* SessionManager::createSession(QString configPath )
session->setArguments( info->arguments() );
session->setTitle( info->name() );
session->setIconName( info->icon() );
session->setSchema( _colorSchemeList->find(activeSetting(ColorScheme).toString()) );
//temporary
session->setHistory( HistoryTypeBuffer(1000) );
//ask for notification when session dies
connect( session , SIGNAL(done(TESession*)) , SLOT(sessionTerminated(TESession*)) );
......
......@@ -31,6 +31,8 @@ class KSimpleConfig;
class KConfig;
class TESession;
class ColorSchemaList;
/**
* Provides information about a type of
* session, including the title of the session
......@@ -262,10 +264,11 @@ private:
SessionInfo* _defaultSessionType;
typedef QPair<Source,QVariant> SourceVariant;
QHash< Setting , QList< SourceVariant > > _settings;
ColorSchemaList* _colorSchemeList;
};
#endif //SESSIONMANAGER_H
......@@ -285,8 +285,8 @@ void TEScreen::deleteChars(int n)
{
if (n == 0) n = 1; // Default
if (n > columns) n = columns - 1;
clearImage(loc(columns-n,cuY),loc(columns-1,cuY),' ');
screenLines[cuY].remove(cuX,n);
}
/*! insert `n' spaces at the cursor position.
......@@ -1415,242 +1415,6 @@ void TEScreen::copyLineToStream(int line , int start, int count,
decoder->decodeLine( (ca*) characterBuffer , count, 0 , stream);
}
#if 0
void TEScreen::getSelText(bool preserve_line_breaks, QTextStream *stream)
{
//TESTING selectedText()
//TerminalCharacterDecoder* decoder = new PlainTextDecoder();
TerminalCharacterDecoder* decoder = new HTMLDecoder();
selectedText( stream , decoder );
delete decoder;
return;
//END-TESTING
if (sel_begin == -1)
return; // Selection got clear while selecting.
int *m; // buffer to fill.
int s, d; // source index, dest. index.
int hist_BR = loc(0, hist->getLines());
int hY = sel_TL / columns;
int hX = sel_TL % columns;
int eol; // end of line
s = sel_TL; // tracks copy in source.
// allocate buffer for maximum
// possible size...
d = (sel_BR - sel_TL) / columns + 1;
m = new int[columns + 3];
d = 0;
#define LINE_END do { \
assert(d <= columns); \
*stream << makeString(m, d, true) << (preserve_line_breaks ? "\n" : " "); \
d = 0; \
} while(false)
#define LINE_WRAP do { \
assert(d <= columns); \
*stream << makeString(m, d, false); \
d = 0; \
} while(false)
#define LINE_FLUSH do { \
assert(d <= columns); \
*stream << makeString(m, d, false); \
d = 0; \
} while(false)
if (columnmode) {
bool newlineneeded=false;
preserve_line_breaks = true; // Just in case
int sel_Left, sel_Right;
if ( sel_TL % columns < sel_BR % columns ) {
sel_Left = sel_TL; sel_Right = sel_BR;
} else {
sel_Left = sel_BR; sel_Right = sel_TL;
}
while (s <= sel_BR) {
if (s < hist_BR) { // get lines from hist->history buffer.
hX = sel_Left % columns;
eol = hist->getLineLen(hY);
if (eol > columns)
eol = columns;
if ((hY == (sel_BR / columns)) &&
(eol > (sel_BR % columns)))
{
eol = sel_BR % columns + 1;
}
while (hX < eol && hX <= sel_Right % columns)
{
Q_UINT16 c = hist->getCell(hY, hX++).c;
if (c)
m[d++] = c;
s++;
}
LINE_END;
hY++;
s = hY * columns;
}
else { // or from screen image.
if (testIsSelected((s - hist_BR) % columns, (s - hist_BR) / columns)) {
Q_UINT16 c = image[s++ - hist_BR].c;
if (c) {
m[d++] = c;
newlineneeded = true;
}
if (((s - hist_BR) % columns == 0) && newlineneeded)
{
LINE_END;
newlineneeded = false;
}
}
else {
s++;
if (newlineneeded) {
LINE_END;
newlineneeded = false;
}
}
}
}
if (newlineneeded)
LINE_END;
}
else
{
while (s <= sel_BR)
{
if (s < hist_BR)
{ // get lines from hist->history buffer.
eol = hist->getLineLen(hY);
if (eol > columns)
eol = columns;
if ((hY == (sel_BR / columns)) &&
(eol > (sel_BR % columns)))
{
eol = sel_BR % columns + 1;
}
while (hX < eol)
{
Q_UINT16 c = hist->getCell(hY, hX++).c;
if (c)
m[d++] = c;
s++;
}
if (s <= sel_BR)
{ // The line break handling
bool wrap = false;
if (eol % columns == 0)
{ // That's either a full or empty line
if ((eol != 0) && hist->isWrappedLine(hY))
wrap = true;
}
else if ((eol + 1) % columns == 0)
{
if (hist->isWrappedLine(hY))
wrap = true;
}
if (wrap)
{
LINE_WRAP;
}
else
{
LINE_END;
}
}
else
{
// Flush trailing stuff
LINE_FLUSH;
}
hY++;
hX = 0;
s = hY * columns;
}
else
{ // or from screen image.
eol = (s / columns + 1) * columns - 1;
bool addNewLine = false;
if (eol < sel_BR)
{
while ((eol > s) &&
(!image[eol - hist_BR].c || isSpace(image[eol - hist_BR].c)) &&
!(lineProperties[(eol-hist_BR)/columns] & LINE_WRAPPED))
{
eol--;
}
}
else if (eol == sel_BR)
{
if (!(lineProperties[(eol - hist_BR)/columns] & LINE_WRAPPED))
addNewLine = true;
}
else
{
eol = sel_BR;
}
while (s <= eol)
{
Q_UINT16 c = image[s++ - hist_BR].c;
if (c)
m[d++] = c;
}
if (eol < sel_BR)
{ // eol processing
bool wrap = false;
if ((eol + 1) % columns == 0)
{ // the whole line is filled
if (lineProperties[(eol - hist_BR)/columns] & LINE_WRAPPED)
wrap = true;
}
if (wrap)
{
LINE_WRAP;
}
else
{
LINE_END;
}
}
else
{
// Flush trailing stuff
if (addNewLine && preserve_line_breaks)
{
LINE_END;
}
else
{
LINE_FLUSH;
}
}
s = (eol / columns + 1) * columns;
}
}
}
assert(d == 0);
delete [] m;
}
#endif
void TEScreen::writeToStream(QTextStream* stream , TerminalCharacterDecoder* decoder) {
sel_begin = 0;
sel_BR = sel_begin;
......
......@@ -1455,6 +1455,10 @@ int TEWidget::scrollPosition()
{
return scrollbar->value();
}
bool TEWidget::scrollAtEnd()
{
return (scrollbar->value() == scrollbar->maximum());
}
void TEWidget::setScroll(int cursor, int slines)
{
......
......@@ -90,6 +90,7 @@ public:
void setScroll(int cursor, int lines);
void doScroll(int lines);
int scrollPosition();
bool scrollAtEnd();
bool blinkingCursor() { return hasBlinkingCursor; }
void setBlinkingCursor(bool blink);
......
......@@ -542,38 +542,32 @@ void TEmulation::showBulk()
QVector<LineProperty> lineProperties;
QListIterator<TEWidget*> viewIter(_views);
const int originalHistCursor = scr->getHistCursor();
// keep track of the scroll position of the previous view
// this allows each view to show a different scroll position,
// but avoids repeatedly getting a new character image and line property set from
// the TEScreen if the views are showing the same image
int prevHistCursor = -1;
image = scr->getCookedImage();
lineProperties = scr->getCookedLineProperties();
while (viewIter.hasNext())
{
TEWidget* view = viewIter.next();
if ( prevHistCursor == -1 || prevHistCursor != view->scrollPosition() )
{
prevHistCursor = view->scrollPosition();
scr->setHistCursor(prevHistCursor);
image = scr->getCookedImage();
lineProperties = scr->getCookedLineProperties();
}
QRect scrollRegion;
scrollRegion.setTop( scr->topMargin() );
scrollRegion.setBottom( scr->bottomMargin() );
scrollRegion.setLeft( 0 );
scrollRegion.setRight( scr->getColumns() );
// this is an optimisation to avoid the view having to redraw the entire display
// when the output is simply scrolled by a few lines.
// scr->scrolledLines() is a guess as to how much the output has scrolled by since
// the last call to scr->resetScrolledLines(). It does not matter if this count is
// wrong since the final output from the view will always be the image set with
// setImage() below.
view->scrollImage( - scr->scrolledLines() , scrollRegion );
// update the display
view->setLineProperties( lineProperties );
view->setImage(image,
scr->getLines(),
scr->getColumns()); // actual refresh
scr->getColumns());
view->setCursorPos(scr->getCursorX(), scr->getCursorY()); // set XIM position
view->setScroll(scr->getHistCursor(),scr->getHistLines());
}
......
......@@ -17,6 +17,9 @@
02110-1301 USA.
*/
// System
#include <assert.h>
// KDE
#include <kdebug.h>
#include <KLocale>
......@@ -27,6 +30,7 @@
#include "KonsoleMainWindow.h"
#include "TESession.h"
#include "TEWidget.h"
#include "schema.h"
#include "SessionController.h"
#include "SessionManager.h"
#include "ViewContainer.h"
......@@ -60,19 +64,21 @@ ViewManager::~ViewManager()
void ViewManager::setupActions()
{
KToggleAction* splitViewAction = new KToggleAction( i18n("&Split View"),
_mainWindow->actionCollection() , "split-view" );
splitViewAction->setCheckedState( KGuiItem(i18n("&Remove Split")) );
connect( splitViewAction , SIGNAL(toggled(bool)) , this , SLOT(splitView(bool)));
KActionCollection* collection = _mainWindow->actionCollection();
_splitViewAction = new KToggleAction( KIcon("view_top_bottom"),i18n("&Split View"),
collection , "split-view" );
_splitViewAction->setCheckedState( KGuiItem(i18n("&Remove Split") , KIcon("view_remove") ) );
connect( _splitViewAction , SIGNAL(toggled(bool)) , this , SLOT(splitView(bool)));
KAction* detachViewAction = new KAction( i18n("&Detach View"),
_mainWindow->actionCollection() , "detach-view" );
KAction* detachViewAction = new KAction( KIcon("view_remove") , i18n("&Detach View"),
collection , "detach-view" );
connect( detachViewAction , SIGNAL(triggered()) , this , SLOT(detachActiveView()) );
KAction* mergeAction = new KAction( i18n("&Merge Windows"),
_mainWindow->actionCollection() , "merge-windows" );
collection , "merge-windows" );
connect( mergeAction , SIGNAL(triggered()) , _mainWindow , SLOT(mergeWindows()) );
}
......@@ -101,6 +107,10 @@ void ViewManager::detachActiveView()
container->views().count() == 0 )
{
delete container;
// this will need to be removed if Konsole is modified so the menu item to
// split the view is no longer one toggle-able item
_splitViewAction->setChecked(false);
}
}
......@@ -126,7 +136,11 @@ void ViewManager::viewFocused( SessionController* controller )
if ( _pluggedController )
_mainWindow->guiFactory()->removeClient(_pluggedController);
// update the menus in the main window to use the actions from the active
// controller
_mainWindow->guiFactory()->addClient(controller);
// update the caption of the main window to match that of the focused session
_mainWindow->setPlainCaption( controller->session()->displayTitle() );
_pluggedController = controller;
}
......@@ -145,7 +159,8 @@ void ViewManager::splitView(bool splitView)
while (existingViewIter.hasNext())
{
TESession* session = _sessionMap[(TEWidget*)existingViewIter.next()];
TEWidget* display = createTerminalDisplay();
TEWidget* display = createTerminalDisplay();
loadViewSettings(display,session);
createController(session,display);
_sessionMap[display] = session;
......@@ -189,6 +204,7 @@ void ViewManager::createView(TESession* session)
{
ViewContainer* container = containerIter.next();
TEWidget* display = createTerminalDisplay();
loadViewSettings(display,session);
createController(session,display);
_sessionMap[display] = session;
......@@ -218,9 +234,16 @@ void ViewManager::merge(ViewManager* otherManager)
while ( otherViewIter.hasNext() )
{
QWidget* view = otherViewIter.next();
TEWidget* view = dynamic_cast<TEWidget*>(otherViewIter.next());
assert(view);
otherContainer->removeView(view);
activeContainer->addView(view);
// transfer the session map entries
_sessionMap.insert(view,otherManager->_sessionMap[view]);
otherManager->_sessionMap.remove(view);
}
}
......@@ -240,4 +263,11 @@ TEWidget* ViewManager::createTerminalDisplay()
return display;
}
void ViewManager::loadViewSettings(TEWidget* view , TESession* session)
{
// load colour scheme
view->setColorTable( session->