PageRenderTime 66ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/mks-svn4458/plugins/base/Tools/src/ToolsManager.cpp

#
C++ | 422 lines | 326 code | 73 blank | 23 comment | 72 complexity | 98e836f738f65d42fd1cef03309a472b MD5 | raw file
Possible License(s): GPL-2.0, GPL-3.0, LGPL-3.0, Zlib, AGPL-1.0
  1. /****************************************************************************
  2. Copyright (C) 2005 - 2011 Filipe AZEVEDO & The Monkey Studio Team
  3. http://monkeystudio.org licensing under the GNU GPL.
  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. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with this program; if not, write to the Free Software
  14. Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  15. ****************************************************************************/
  16. #include "ToolsManager.h"
  17. #include "ui/UIToolsEdit.h"
  18. #include "ui/UIDesktopTools.h"
  19. #include <coremanager/MonkeyCore.h>
  20. #include <consolemanager/pConsoleManager.h>
  21. #include <pQueuedMessageToolBar.h>
  22. #include <settingsmanager/Settings.h>
  23. #include <shellmanager/MkSShellInterpreter.h>
  24. #include <pMenuBar.h>
  25. #include <QFileIconProvider>
  26. #include <QDesktopServices>
  27. #include <QImageReader>
  28. #include <QUrl>
  29. #include <QDebug>
  30. QFileIconProvider* ToolsManager::mIconProvider = 0;
  31. ToolsManager::ToolsManager( QObject* p )
  32. : QObject( p )
  33. {
  34. if ( !mIconProvider ) {
  35. mIconProvider = new QFileIconProvider();
  36. }
  37. initializeInterpreterCommands( true );
  38. }
  39. ToolsManager::~ToolsManager()
  40. {
  41. initializeInterpreterCommands( false );
  42. delete mIconProvider;
  43. mIconProvider = 0;
  44. writeTools( mTools );
  45. }
  46. QString ToolsManager::scriptFilePath() const
  47. {
  48. return MonkeyCore::settings()->homePath( Settings::SP_SCRIPTS ).append( "/tools.mks" );
  49. }
  50. ToolsManager::Tools ToolsManager::tools( ToolsManager::Type type ) const
  51. {
  52. ToolsManager::Tools tools;
  53. foreach ( const ToolsManager::Tool& tool, mTools ) {
  54. if ( ( tool.desktopEntry && type == ToolsManager::DesktopEntry )
  55. || ( !tool.desktopEntry && type == ToolsManager::UserEntry ) ) {
  56. tools << tool;
  57. }
  58. }
  59. return tools;
  60. }
  61. void ToolsManager::setCommand( const QString& caption, const QString& fileIcon, const QString& filePath, const QString& workingPath, bool desktopEntry, bool useConsoleManager )
  62. {
  63. for ( int i = 0; i < mTools.count(); i++ ) {
  64. ToolsManager::Tool& tool = mTools[ i ];
  65. if ( tool.caption == caption ) {
  66. tool.fileIcon = fileIcon;
  67. tool.filePath = filePath;
  68. tool.workingPath = workingPath;
  69. tool.desktopEntry = desktopEntry;
  70. tool.useConsoleManager = useConsoleManager;
  71. return;
  72. }
  73. }
  74. mTools << ToolsManager::Tool( caption, fileIcon, filePath, workingPath, desktopEntry, useConsoleManager );
  75. }
  76. void ToolsManager::unsetCommand( const QString& caption )
  77. {
  78. for ( int i = 0; i < mTools.count(); i++ ) {
  79. ToolsManager::Tool& tool = mTools[ i ];
  80. if ( tool.caption == caption ) {
  81. mTools.removeAt( i );
  82. return;
  83. }
  84. }
  85. }
  86. void ToolsManager::clearCommand()
  87. {
  88. mTools.clear();
  89. }
  90. void ToolsManager::updateMenuCommand()
  91. {
  92. updateMenuActions();
  93. }
  94. QIcon ToolsManager::icon( const QString& filePath, const QString& optionnalFilePath )
  95. {
  96. const bool filePathValid = filePath.isEmpty() ? false : !QImageReader::imageFormat( filePath ).isEmpty();
  97. const bool optionnalFilePathValid = optionnalFilePath.isEmpty() ? false : !QImageReader::imageFormat( optionnalFilePath ).isEmpty();
  98. QIcon icon;
  99. if ( filePathValid ) {
  100. icon = QIcon( filePath );
  101. #if QT_VERSION >= 0x040600
  102. }
  103. else {
  104. icon = QIcon::fromTheme( filePath, icon );
  105. #endif
  106. }
  107. if ( icon.isNull() ) {
  108. if ( optionnalFilePathValid ) {
  109. icon = QIcon( optionnalFilePath );
  110. #if QT_VERSION >= 0x040600
  111. }
  112. else {
  113. icon = QIcon::fromTheme( optionnalFilePath, icon );
  114. #endif
  115. }
  116. }
  117. if ( icon.isNull() && !filePath.isEmpty() ) {
  118. icon = mIconProvider->icon( filePath );
  119. }
  120. if ( icon.isNull() && !optionnalFilePath.isEmpty() ) {
  121. icon = mIconProvider->icon( optionnalFilePath );
  122. }
  123. return icon;
  124. }
  125. void ToolsManager::updateMenuActions()
  126. {
  127. // get menu bar
  128. pMenuBar* mb = MonkeyCore::menuBar();
  129. // clear action
  130. qDeleteAll( mb->menu( "mTools/mUserTools" )->actions() );
  131. qDeleteAll( mb->menu( "mTools/mDesktopTools" )->actions() );
  132. // initialize tools
  133. foreach ( const ToolsManager::Tool& tool, mTools ) {
  134. QAction* action;
  135. if ( tool.desktopEntry ) {
  136. action = mb->action( QString( "mTools/mDesktopTools/%1" ).arg( tool.caption ), tool.caption, icon( tool.fileIcon, tool.filePath ), QString::null, tr( "Execute tool '%1': %2" ).arg( tool.caption ).arg( tool.filePath ) );
  137. }
  138. else {
  139. action = mb->action( QString( "mTools/mUserTools/%1" ).arg( tool.caption ), tool.caption, icon( tool.fileIcon, tool.filePath ), QString::null, tr( "Execute tool '%1': %2" ).arg( tool.caption ).arg( tool.filePath ) );
  140. }
  141. action->setData( QVariant::fromValue<ToolsManager::Tool>( tool ) );
  142. }
  143. }
  144. void ToolsManager::editTools_triggered()
  145. {
  146. QAction* action = qobject_cast<QAction*>( sender() );
  147. QDialog* dlg = 0;
  148. switch ( ToolsManager::Type( action->data().toInt() ) )
  149. {
  150. case ToolsManager::UserEntry:
  151. dlg = new UIToolsEdit( this, QApplication::activeWindow() );
  152. break;
  153. case ToolsManager::DesktopEntry:
  154. dlg = new UIDesktopTools( this, QApplication::activeWindow() );
  155. break;
  156. }
  157. dlg->open();
  158. }
  159. void ToolsManager::toolsMenu_triggered( QAction* action )
  160. {
  161. pConsoleManager* cm = MonkeyCore::consoleManager();
  162. const ToolsManager::Tool tool = action->data().value<ToolsManager::Tool>();
  163. const QString filePath = cm->processInternalVariables( tool.filePath, false );
  164. const QString workingPath = cm->processInternalVariables( tool.workingPath, false );
  165. bool ok = false;
  166. if ( filePath.isEmpty() ) {
  167. ok = false;
  168. }
  169. else if ( tool.useConsoleManager ) {
  170. pCommand cmd;
  171. cmd.setName( tool.caption );
  172. cmd.setText( tool.caption );
  173. QStringList commandAndArgs = filePath.split( ' ' );
  174. cmd.setCommand( commandAndArgs.join( " " ).prepend( " " ).prepend( commandAndArgs.takeFirst() ) );
  175. cmd.setWorkingDirectory( workingPath );
  176. cmd.setTryAllParsers( true );
  177. cm->addCommand( cmd );
  178. ok = true;
  179. }
  180. else if ( workingPath.isEmpty() && QFile::exists( filePath ) ) {
  181. ok = QDesktopServices::openUrl( QUrl::fromLocalFile( filePath ) );
  182. }
  183. else if ( workingPath.isEmpty() ) {
  184. ok = QProcess::startDetached( filePath );
  185. }
  186. else {
  187. QProcess* process = new QProcess( this );
  188. connect( process, SIGNAL( finished( int ) ), process, SLOT( deleteLater() ) );
  189. process->setWorkingDirectory( workingPath );
  190. process->start( filePath );
  191. ok = process->waitForStarted();
  192. }
  193. if ( !ok ) {
  194. MonkeyCore::messageManager()->appendMessage( tr( "Error trying to start tool: '%1'" ).arg( filePath ) );
  195. }
  196. }
  197. bool ToolsManager::writeTools( const ToolsManager::Tools& tools ) const
  198. {
  199. // write content in utf8
  200. const QString fn = scriptFilePath();
  201. QFile file( fn );
  202. QStringList buffer;
  203. if ( !file.open( QIODevice::WriteOnly ) ) {
  204. qWarning() << QString( "Can't open file for generating tools script: %1" ).arg( file.errorString() ).toLocal8Bit().constData();
  205. return false;
  206. }
  207. file.resize( 0 );
  208. buffer << "# Monkey Studio IDE Tools";
  209. buffer << "# reset tools";
  210. buffer << "tools clear";
  211. buffer << "# Available commands:";
  212. buffer << "# tools set caption fileIcon filePath workingPath desktopEntry useConsoleManager";
  213. buffer << "# tools unset caption";
  214. buffer << "# tools clear";
  215. buffer << "# tools update-menu";
  216. buffer << "# tools list";
  217. buffer << "# introduce new tools";
  218. foreach ( const Tool& tool, tools ) {
  219. buffer << QString( "# %1" ).arg( tool.caption );
  220. buffer << QString( "tools set \"%1\" \"%2\" \"%3\" \"%4\" \"%5\" \"%6\"" )
  221. .arg( tool.caption )
  222. .arg( tool.fileIcon )
  223. .arg( tool.filePath )
  224. .arg( tool.workingPath )
  225. .arg( tool.desktopEntry )
  226. .arg( tool.useConsoleManager );
  227. }
  228. buffer << "# Update the menu";
  229. buffer << "tools update-menu";
  230. if ( file.write( buffer.join( "\n" ).toUtf8() ) == -1 ) {
  231. qWarning() << QString( "Can't write generated tools script: %1" ).arg( file.errorString() ).toLocal8Bit().constData();
  232. }
  233. file.close();
  234. return true;
  235. }
  236. void ToolsManager::initializeInterpreterCommands( bool initialize )
  237. {
  238. if ( initialize ) {
  239. // register command
  240. QString help = MkSShellInterpreter::tr(
  241. "This command manage the tools, usage:\n"
  242. "\ttools set [caption] [fileIcon] [filePath] [workingPath] [desktopEntry:true|false] [useConsoleManager:true|false]\n"
  243. "\ttools unset [caption]\n"
  244. "\ttools clear\n"
  245. "\ttools update-menu\n"
  246. "\ttools list"
  247. );
  248. MonkeyCore::interpreter()->addCommandImplementation( "tools", ToolsManager::commandInterpreter, help, this );
  249. }
  250. else {
  251. MonkeyCore::interpreter()->removeCommandImplementation( "tools" );
  252. }
  253. }
  254. QString ToolsManager::commandInterpreter( const QString& command, const QStringList& _arguments, int* result, MkSShellInterpreter* interpreter, void* data )
  255. {
  256. Q_UNUSED( command );
  257. Q_UNUSED( interpreter );
  258. ToolsManager* manager = static_cast<ToolsManager*>( data );
  259. QStringList arguments = _arguments;
  260. const QStringList allowedOperations = QStringList( "set" ) << "unset" << "clear" << "update-menu" << "list";
  261. if ( result ) {
  262. *result = MkSShellInterpreter::NoError;
  263. }
  264. if ( arguments.isEmpty() ) {
  265. if ( result ) {
  266. *result = MkSShellInterpreter::InvalidCommand;
  267. }
  268. return MkSShellInterpreter::tr( "Operation not defined. Available operations are: %1." ).arg( allowedOperations.join( ", " ) );
  269. }
  270. const QString operation = arguments.takeFirst();
  271. if ( !allowedOperations.contains( operation ) ) {
  272. if ( result ) {
  273. *result = MkSShellInterpreter::InvalidCommand;
  274. }
  275. return MkSShellInterpreter::tr( "Unknown operation: '%1'." ).arg( operation );
  276. }
  277. if ( operation == "set" ) {
  278. if ( arguments.count() != 6 ) {
  279. if ( result ) {
  280. *result = MkSShellInterpreter::InvalidCommand;
  281. }
  282. return MkSShellInterpreter::tr( "'set' operation take 6 arguments, %1 given." ).arg( arguments.count() );
  283. }
  284. const QString caption = arguments.at( 0 );
  285. const QString fileIcon = arguments.at( 1 );
  286. const QString filePath = arguments.at( 2 );
  287. const QString workingPath = arguments.at( 3 );
  288. const bool desktopEntry = QVariant( arguments.at( 4 ) ).toBool();
  289. const bool useConsoleManager = QVariant( arguments.at( 5 ) ).toBool();
  290. manager->setCommand( caption, fileIcon, filePath, workingPath, desktopEntry, useConsoleManager );
  291. }
  292. if ( operation == "unset" ) {
  293. if ( arguments.count() != 1 ) {
  294. if ( result ) {
  295. *result = MkSShellInterpreter::InvalidCommand;
  296. }
  297. return MkSShellInterpreter::tr( "'unset' operation take 1 arguments, %1 given." ).arg( arguments.count() );
  298. }
  299. const QString caption = arguments.at( 0 );
  300. manager->unsetCommand( caption );
  301. }
  302. if ( operation == "clear" ) {
  303. if ( arguments.count() != 0 ) {
  304. if ( result ) {
  305. *result = MkSShellInterpreter::InvalidCommand;
  306. }
  307. return MkSShellInterpreter::tr( "'clear' operation take no arguments, %1 given." ).arg( arguments.count() );
  308. }
  309. manager->clearCommand();
  310. }
  311. if ( operation == "update-menu" ) {
  312. if ( arguments.count() != 0 ) {
  313. if ( result ) {
  314. *result = MkSShellInterpreter::InvalidCommand;
  315. }
  316. return MkSShellInterpreter::tr( "'update-menu' operation take no arguments, %1 given." ).arg( arguments.count() );
  317. }
  318. manager->updateMenuCommand();
  319. }
  320. if ( operation == "list" ) {
  321. if ( arguments.count() != 0 ) {
  322. if ( result ) {
  323. *result = MkSShellInterpreter::InvalidCommand;
  324. }
  325. return MkSShellInterpreter::tr( "'list' operation take no arguments, %1 given." ).arg( arguments.count() );
  326. }
  327. QStringList output;
  328. foreach ( const ToolsManager::Tool& tool, manager->mTools ) {
  329. output << QString( "%1: \"%2\" \"%3\" \"%4\" \"%5\" \"%6\"" )
  330. .arg( tool.caption )
  331. .arg( tool.fileIcon )
  332. .arg( tool.filePath )
  333. .arg( tool.workingPath )
  334. .arg( tool.desktopEntry )
  335. .arg( tool.useConsoleManager );
  336. }
  337. if ( !output.isEmpty() ) {
  338. output.prepend( MkSShellInterpreter::tr( "Found tools:" ) );
  339. }
  340. else {
  341. output << MkSShellInterpreter::tr( "No tools found." );
  342. }
  343. return output.join( "\n" );
  344. }
  345. return QString::null;
  346. }