• Skip to content
  • Skip to link menu
KDE API Reference
  • KDE API Reference
  • applications API Reference
  • KDE Home
  • Contact Us
 

Konsole

  • kde-4.14
  • applications
  • konsole
  • src
Application.cpp
Go to the documentation of this file.
1 /*
2  Copyright 2006-2008 by Robert Knight <robertknight@gmail.com>
3 
4  This program is free software; you can redistribute it and/or modify
5  it under the terms of the GNU General Public License as published by
6  the Free Software Foundation; either version 2 of the License, or
7  (at your option) any later version.
8 
9  This program is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  GNU General Public License for more details.
13 
14  You should have received a copy of the GNU General Public License
15  along with this program; if not, write to the Free Software
16  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17  02110-1301 USA.
18 */
19 
20 // Own
21 #include "Application.h"
22 
23 // Qt
24 #include <QtCore/QHashIterator>
25 #include <QtCore/QFileInfo>
26 #include <QtCore/QDir>
27 
28 // KDE
29 #include <KAction>
30 #include <KActionCollection>
31 #include <KCmdLineArgs>
32 #include <KDebug>
33 #include <KStandardDirs>
34 
35 // Konsole
36 #include "SessionManager.h"
37 #include "ProfileManager.h"
38 #include "MainWindow.h"
39 #include "Session.h"
40 #include "ShellCommand.h"
41 
42 using namespace Konsole;
43 
44 Application::Application() : KUniqueApplication()
45 {
46  init();
47 }
48 
49 void Application::init()
50 {
51  _backgroundInstance = 0;
52 
53 #if defined(Q_WS_MAC)
54  // this ensures that Ctrl and Meta are not swapped, so CTRL-C and friends
55  // will work correctly in the terminal
56  setAttribute(Qt::AA_MacDontSwapCtrlAndMeta);
57 
58  // KDE's menuBar()->isTopLevel() hasn't worked in a while.
59  // For now, put menus inside Konsole window; this also make
60  // the keyboard shortcut to show menus look reasonable.
61  setAttribute(Qt::AA_DontUseNativeMenuBar);
62 #endif
63 }
64 
65 Application::~Application()
66 {
67  SessionManager::instance()->closeAllSessions();
68  ProfileManager::instance()->saveSettings();
69 }
70 
71 MainWindow* Application::newMainWindow()
72 {
73  MainWindow* window = new MainWindow();
74 
75  connect(window, SIGNAL(newWindowRequest(Profile::Ptr,QString)),
76  this, SLOT(createWindow(Profile::Ptr,QString)));
77  connect(window, SIGNAL(viewDetached(Session*)),
78  this, SLOT(detachView(Session*)));
79 
80  return window;
81 }
82 
83 void Application::createWindow(Profile::Ptr profile, const QString& directory)
84 {
85  MainWindow* window = newMainWindow();
86  window->createSession(profile, directory);
87  window->show();
88 }
89 
90 void Application::detachView(Session* session)
91 {
92  MainWindow* window = newMainWindow();
93  window->createView(session);
94  // Since user is dragging and dropping, move dnd window to where
95  // the user has the cursor (correct multiple monitor setups).
96  window->move(QCursor::pos());
97  window->show();
98 }
99 
100 int Application::newInstance()
101 {
102  static bool firstInstance = true;
103 
104  KCmdLineArgs* args = KCmdLineArgs::parsedArgs();
105 
106  // handle session management
107  if ((args->count() != 0) || !firstInstance || !isSessionRestored()) {
108  // check for arguments to print help or other information to the
109  // terminal, quit if such an argument was found
110  if (processHelpArgs(args))
111  return 0;
112 
113  // create a new window or use an existing one
114  MainWindow* window = processWindowArgs(args);
115 
116  if (args->isSet("tabs-from-file")) {
117  // create new session(s) as described in file
118  processTabsFromFileArgs(args, window);
119  } else {
120  // select profile to use
121  Profile::Ptr baseProfile = processProfileSelectArgs(args);
122 
123  // process various command-line options which cause a property of the
124  // selected profile to be changed
125  Profile::Ptr newProfile = processProfileChangeArgs(args, baseProfile);
126 
127  // create new session
128  Session* session = window->createSession(newProfile, QString());
129 
130  if (!args->isSet("close")) {
131  session->setAutoClose(false);
132  }
133  }
134 
135  // if the background-mode argument is supplied, start the background
136  // session ( or bring to the front if it already exists )
137  if (args->isSet("background-mode")) {
138  startBackgroundMode(window);
139  } else {
140  // Qt constrains top-level windows which have not been manually
141  // resized (via QWidget::resize()) to a maximum of 2/3rds of the
142  // screen size.
143  //
144  // This means that the terminal display might not get the width/
145  // height it asks for. To work around this, the widget must be
146  // manually resized to its sizeHint().
147  //
148  // This problem only affects the first time the application is run.
149  // run. After that KMainWindow will have manually resized the
150  // window to its saved size at this point (so the Qt::WA_Resized
151  // attribute will be set)
152  if (!window->testAttribute(Qt::WA_Resized))
153  window->resize(window->sizeHint());
154 
155  window->show();
156  }
157  }
158 
159  firstInstance = false;
160  args->clear();
161  return 0;
162 }
163 
164 /* Documentation for tab file:
165  *
166  * ;; is the token separator
167  * # at the beginning of line results in line being ignored.
168  * supported tokens are title, command and profile.
169  *
170  * Note that the title is static and the tab will close when the
171  * command is complete (do not use --noclose). You can start new tabs.
172  *
173  * Examples:
174 title: This is the title;; command: ssh jupiter
175 title: Top this!;; command: top
176 #this line is comment
177 command: ssh earth
178 profile: Zsh
179 */
180 void Application::processTabsFromFileArgs(KCmdLineArgs* args,
181  MainWindow* window)
182 {
183  // Open tab configuration file
184  const QString tabsFileName(args->getOption("tabs-from-file"));
185  QFile tabsFile(tabsFileName);
186  if (!tabsFile.open(QFile::ReadOnly)) {
187  kWarning() << "ERROR: Cannot open tabs file "
188  << tabsFileName.toLocal8Bit().data();
189  quit();
190  }
191 
192  unsigned int sessions = 0;
193  while (!tabsFile.atEnd()) {
194  QString lineString(tabsFile.readLine().trimmed());
195  if ((lineString.isEmpty()) || (lineString[0] == '#'))
196  continue;
197 
198  QHash<QString, QString> lineTokens;
199  QStringList lineParts = lineString.split(";;", QString::SkipEmptyParts);
200 
201  for (int i = 0; i < lineParts.size(); ++i) {
202  QString key = lineParts.at(i).section(':', 0, 0).trimmed().toLower();
203  QString value = lineParts.at(i).section(':', 1, -1).trimmed();
204  lineTokens[key] = value;
205  }
206  // should contain at least one of 'command' and 'profile'
207  if (lineTokens.contains("command") || lineTokens.contains("profile")) {
208  createTabFromArgs(args, window, lineTokens);
209  sessions++;
210  } else {
211  kWarning() << "Each line should contain at least one of 'command' and 'profile'.";
212  }
213  }
214  tabsFile.close();
215 
216  if (sessions < 1) {
217  kWarning() << "No valid lines found in "
218  << tabsFileName.toLocal8Bit().data();
219  quit();
220  }
221 }
222 
223 void Application::createTabFromArgs(KCmdLineArgs* args, MainWindow* window,
224  const QHash<QString, QString>& tokens)
225 {
226  const QString& title = tokens["title"];
227  const QString& command = tokens["command"];
228  const QString& profile = tokens["profile"];
229  const QString& workdir = tokens["workdir"];
230 
231  Profile::Ptr baseProfile;
232  if (!profile.isEmpty()) {
233  baseProfile = ProfileManager::instance()->loadProfile(profile);
234  }
235  if (!baseProfile) {
236  // fallback to default profile
237  baseProfile = ProfileManager::instance()->defaultProfile();
238  }
239 
240  Profile::Ptr newProfile = Profile::Ptr(new Profile(baseProfile));
241  newProfile->setHidden(true);
242 
243  // FIXME: the method of determining whether to use newProfile does not
244  // scale well when we support more fields in the future
245  bool shouldUseNewProfile = false;
246 
247  if (!command.isEmpty()) {
248  newProfile->setProperty(Profile::Command, command);
249  newProfile->setProperty(Profile::Arguments, command.split(' '));
250  shouldUseNewProfile = true;
251  }
252 
253  if (!title.isEmpty()) {
254  newProfile->setProperty(Profile::LocalTabTitleFormat, title);
255  newProfile->setProperty(Profile::RemoteTabTitleFormat, title);
256  shouldUseNewProfile = true;
257  }
258 
259  if (args->isSet("workdir")) {
260  newProfile->setProperty(Profile::Directory, args->getOption("workdir"));
261  shouldUseNewProfile = true;
262  }
263 
264  if (!workdir.isEmpty()) {
265  newProfile->setProperty(Profile::Directory, workdir);
266  shouldUseNewProfile = true;
267  }
268 
269  // Create the new session
270  Profile::Ptr theProfile = shouldUseNewProfile ? newProfile : baseProfile;
271  Session* session = window->createSession(theProfile, QString());
272 
273  if (!args->isSet("close")) {
274  session->setAutoClose(false);
275  }
276 
277  if (!window->testAttribute(Qt::WA_Resized)) {
278  window->resize(window->sizeHint());
279  }
280 
281  // FIXME: this ugly hack here is to make the session start running, so that
282  // its tab title is displayed as expected.
283  //
284  // This is another side effect of the commit fixing BKO 176902.
285  window->show();
286  window->hide();
287 }
288 
289 MainWindow* Application::processWindowArgs(KCmdLineArgs* args)
290 {
291  MainWindow* window = 0;
292  if (args->isSet("new-tab")) {
293  QListIterator<QWidget*> iter(topLevelWidgets());
294  iter.toBack();
295  while (iter.hasPrevious()) {
296  window = qobject_cast<MainWindow*>(iter.previous());
297  if (window != 0)
298  break;
299  }
300  }
301 
302  if (window == 0) {
303  window = newMainWindow();
304 
305  // override default menubar visibility
306  if (args->isSet("show-menubar")) {
307  window->setMenuBarInitialVisibility(true);
308  }
309  if (args->isSet("hide-menubar")) {
310  window->setMenuBarInitialVisibility(false);
311  }
312  if (args->isSet("fullscreen")) {
313  window->viewFullScreen(true);
314  }
315 
316  // override default tabbbar visibility
317  // FIXME: remove those magic number
318  // see ViewContainer::NavigationVisibility
319  if (args->isSet("show-tabbar")) {
320  // always show
321  window->setNavigationVisibility(0);
322  }
323  if (args->isSet("hide-tabbar")) {
324  // never show
325  window->setNavigationVisibility(2);
326  }
327  }
328  return window;
329 }
330 
331 Profile::Ptr Application::processProfileSelectArgs(KCmdLineArgs* args)
332 {
333  Profile::Ptr defaultProfile = ProfileManager::instance()->defaultProfile();
334 
335  if (args->isSet("profile")) {
336  Profile::Ptr profile = ProfileManager::instance()->loadProfile(
337  args->getOption("profile"));
338  if (profile)
339  return profile;
340  } else if (args->isSet("fallback-profile")) {
341  Profile::Ptr profile = ProfileManager::instance()->loadProfile("FALLBACK/");
342  if (profile)
343  return profile;
344  }
345 
346  return defaultProfile;
347 }
348 
349 bool Application::processHelpArgs(KCmdLineArgs* args)
350 {
351  if (args->isSet("list-profiles")) {
352  listAvailableProfiles();
353  return true;
354  } else if (args->isSet("list-profile-properties")) {
355  listProfilePropertyInfo();
356  return true;
357  }
358  return false;
359 }
360 
361 void Application::listAvailableProfiles()
362 {
363  QStringList paths = ProfileManager::instance()->availableProfilePaths();
364 
365  foreach(const QString& path, paths) {
366  QFileInfo info(path);
367  printf("%s\n", info.completeBaseName().toLocal8Bit().constData());
368  }
369 
370  quit();
371 }
372 
373 void Application::listProfilePropertyInfo()
374 {
375  Profile::Ptr tempProfile = ProfileManager::instance()->defaultProfile();
376  const QStringList names = tempProfile->propertiesInfoList();
377 
378  foreach(const QString& name, names) {
379  printf("%s\n", name.toLocal8Bit().constData());
380  }
381 
382  quit();
383 }
384 
385 Profile::Ptr Application::processProfileChangeArgs(KCmdLineArgs* args, Profile::Ptr baseProfile)
386 {
387  bool shouldUseNewProfile = false;
388 
389  Profile::Ptr newProfile = Profile::Ptr(new Profile(baseProfile));
390  newProfile->setHidden(true);
391 
392  // change the initial working directory
393  if (args->isSet("workdir")) {
394  newProfile->setProperty(Profile::Directory, args->getOption("workdir"));
395  shouldUseNewProfile = true;
396  }
397 
398  // temporary changes to profile options specified on the command line
399  foreach(const QString & value , args->getOptionList("p")) {
400  ProfileCommandParser parser;
401 
402  QHashIterator<Profile::Property, QVariant> iter(parser.parse(value));
403  while (iter.hasNext()) {
404  iter.next();
405  newProfile->setProperty(iter.key(), iter.value());
406  }
407 
408  shouldUseNewProfile = true;
409  }
410 
411  // run a custom command
412  if (args->isSet("e")) {
413  QString commandExec = args->getOption("e");
414  QStringList commandArguments;
415 
416  // Note: KCmdLineArgs::count() return the number of arguments
417  // that aren't options.
418  if (args->count() == 0 && KStandardDirs::findExe(commandExec).isEmpty()) {
419  // Example: konsole -e "man ls"
420  ShellCommand shellCommand(args->getOption("e"));
421  commandExec = shellCommand.command();
422  commandArguments = shellCommand.arguments();
423  } else {
424  // Example: konsole -e man ls
425  commandArguments << commandExec;
426  for ( int i = 0 ; i < args->count() ; i++ )
427  commandArguments << args->arg(i);
428  }
429 
430  if (commandExec.startsWith(QLatin1String("./")))
431  commandExec = QDir::currentPath() + commandExec.mid(1);
432 
433  newProfile->setProperty(Profile::Command, commandExec);
434  newProfile->setProperty(Profile::Arguments, commandArguments);
435 
436  shouldUseNewProfile = true;
437  }
438 
439  if (shouldUseNewProfile) {
440  return newProfile;
441  } else {
442  return baseProfile;
443  }
444 }
445 
446 void Application::startBackgroundMode(MainWindow* window)
447 {
448  if (_backgroundInstance) {
449  return;
450  }
451 
452  KAction* action = window->actionCollection()->addAction("toggle-background-window");
453  action->setObjectName(QLatin1String("Konsole Background Mode"));
454  action->setText(i18n("Toggle Background Window"));
455  action->setGlobalShortcut(KShortcut(QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_F12)));
456 
457  connect(action, SIGNAL(triggered()),
458  this, SLOT(toggleBackgroundInstance()));
459 
460  _backgroundInstance = window;
461 }
462 
463 void Application::toggleBackgroundInstance()
464 {
465  Q_ASSERT(_backgroundInstance);
466 
467  if (!_backgroundInstance->isVisible()) {
468  _backgroundInstance->show();
469  // ensure that the active terminal display has the focus. Without
470  // this, an odd problem occurred where the focus widget would change
471  // each time the background instance was shown
472  _backgroundInstance->setFocus();
473  } else {
474  _backgroundInstance->hide();
475  }
476 }
477 
478 #include "Application.moc"
479 
Session.h
Konsole::SessionManager::instance
static SessionManager * instance()
Returns the session manager instance.
Definition: SessionManager.cpp:69
Konsole::Session
Represents a terminal session consisting of a pseudo-teletype and a terminal emulation.
Definition: Session.h:78
Konsole::ProfileManager::availableProfilePaths
QStringList availableProfilePaths() const
Searches for available profiles on-disk and returns a list of paths of profiles which can be loaded...
Definition: ProfileManager.cpp:190
Konsole::ProfileCommandParser
Parses an input string consisting of property names and assigned values and returns a table of proper...
Definition: Profile.h:681
Konsole::Application::~Application
virtual ~Application()
Definition: Application.cpp:65
Application.h
QString::split
QStringList split(const QString &sep, SplitBehavior behavior, Qt::CaseSensitivity cs) const
QList::at
const T & at(int i) const
Konsole::MainWindow::setMenuBarInitialVisibility
void setMenuBarInitialVisibility(bool visible)
Set the initial visibility of the menubar.
Definition: MainWindow.cpp:805
Konsole::Profile::RemoteTabTitleFormat
(QString) The format used for tab titles when the session is running a remote command (eg...
Definition: Profile.h:116
MainWindow.h
Konsole::Application::newInstance
virtual int newInstance()
Creates a new main window and opens a default terminal session.
Definition: Application.cpp:100
Konsole::Application::newMainWindow
MainWindow * newMainWindow()
Creates a new, empty main window and connects to its newSessionRequest() and newWindowRequest() signa...
Definition: Application.cpp:71
QDir::currentPath
QString currentPath()
Konsole::Profile
Represents a terminal set-up which can be used to set the initial state of new terminal sessions or a...
Definition: Profile.h:60
ShellCommand.h
Konsole::Profile::Directory
(QString) The initial working directory for sessions created using this profile.
Definition: Profile.h:108
QFile
QList::size
int size() const
Konsole::Profile::Command
(QString) The command to execute ( excluding arguments ) when creating a new terminal session using t...
Definition: Profile.h:93
Konsole::ProfileManager::defaultProfile
Profile::Ptr defaultProfile() const
Returns a Profile object describing the default profile.
Definition: ProfileManager.cpp:308
Konsole::ProfileManager::saveSettings
void saveSettings()
Saves settings (favorites, shortcuts, default profile etc.) to disk.
Definition: ProfileManager.cpp:272
Konsole::ShellCommand
A class to parse and extract information about shell commands.
Definition: ShellCommand.h:52
Konsole::MainWindow::createView
void createView(Session *session)
create view for the specified session
Definition: MainWindow.cpp:519
Konsole::ProfileManager::instance
static ProfileManager * instance()
Returns the profile manager instance.
Definition: ProfileManager.cpp:114
QHash
Konsole::SessionManager::closeAllSessions
void closeAllSessions()
Kill all running sessions.
Definition: SessionManager.cpp:74
QHashIterator
QString::isEmpty
bool isEmpty() const
QByteArray::constData
const char * constData() const
Konsole::Profile::Arguments
(QStringList) The arguments which are passed to the program specified by the Command property when cr...
Definition: Profile.h:98
Konsole::MainWindow::viewFullScreen
void viewFullScreen(bool fullScreen)
Definition: MainWindow.cpp:362
QString
Konsole::MainWindow
The main window.
Definition: MainWindow.h:57
QStringList
QFileInfo
QString::toLocal8Bit
QByteArray toLocal8Bit() const
QHashIterator::next
Item next()
Konsole::ProfileCommandParser::parse
QHash< Profile::Property, QVariant > parse(const QString &input)
Parses an input string consisting of property names and assigned values and returns a table of proper...
Definition: Profile.cpp:305
Konsole::Profile::Ptr
KSharedPtr< Profile > Ptr
Definition: Profile.h:67
QString::mid
QString mid(int position, int n) const
QCursor::pos
QPoint pos()
QLatin1String
QKeySequence
ProfileManager.h
Konsole::MainWindow::setFocus
void setFocus()
Helper method to make this window get input focus.
Definition: MainWindow.cpp:524
QStringList::split
QStringList split(const QString &sep, const QString &str, bool allowEmptyEntries)
Konsole::Session::setAutoClose
void setAutoClose(bool close)
Specifies whether to close the session automatically when the terminal process terminates.
Definition: Session.cpp:1143
KUniqueApplication
SessionManager.h
QHash::contains
bool contains(const Key &key) const
QListIterator
Konsole::Application::Application
Application()
Constructs a new Konsole application.
Definition: Application.cpp:44
Konsole::ProfileManager::loadProfile
Profile::Ptr loadProfile(const QString &path)
Loads a profile from the specified path and registers it with the ProfileManager. ...
Definition: ProfileManager.cpp:119
Konsole::MainWindow::setNavigationVisibility
void setNavigationVisibility(int visibility)
Definition: MainWindow.cpp:719
Konsole::Profile::LocalTabTitleFormat
(QString) The format used for tab titles when running normal commands.
Definition: Profile.h:112
Konsole::MainWindow::createSession
Session * createSession(Profile::Ptr profile, const QString &directory)
Create a new session.
Definition: MainWindow.cpp:469
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Sat May 9 2020 03:56:27 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

Konsole

Skip menu "Konsole"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members
  • Related Pages

applications API Reference

Skip menu "applications API Reference"
  •   kate
  •       kate
  •   KTextEditor
  •   Kate
  • Konsole

Search



Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal