source: smplayer/trunk/src/smplayer.cpp@ 128

Last change on this file since 128 was 128, checked in by Silvan Scherrer, 13 years ago

SMPlayer: trunk update to latest svn

  • Property svn:eol-style set to LF
File size: 14.3 KB
Line 
1/* smplayer, GUI front-end for mplayer.
2 Copyright (C) 2006-2012 Ricardo Villalba <rvm@users.sourceforge.net>
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17*/
18
19#include "smplayer.h"
20#include "defaultgui.h"
21#include "minigui.h"
22#include "mpcgui.h"
23#include "global.h"
24#include "paths.h"
25#include "translator.h"
26#include "version.h"
27#include "config.h"
28#include "clhelp.h"
29#include "myapplication.h"
30
31#include <QDir>
32#include <QUrl>
33#include <QTime>
34#include <stdio.h>
35
36#ifdef Q_OS_WIN
37#if USE_ASSOCIATIONS
38#include "extensions.h"
39#include "winfileassoc.h" //required for Uninstall
40#endif
41#endif
42
43using namespace Global;
44
45BaseGui * SMPlayer::main_window = 0;
46
47SMPlayer::SMPlayer(const QString & config_path, QObject * parent )
48 : QObject(parent)
49{
50#ifdef LOG_SMPLAYER
51 qInstallMsgHandler( SMPlayer::myMessageOutput );
52 allow_to_send_log_to_gui = true;
53#endif
54
55 gui_to_use = "DefaultGui";
56
57 close_at_end = -1; // Not set
58 start_in_fullscreen = -1; // Not set
59
60 move_gui = false;
61 resize_gui = false;
62
63 Paths::setAppPath( qApp->applicationDirPath() );
64
65#ifndef PORTABLE_APP
66 if (config_path.isEmpty()) createConfigDirectory();
67#endif
68 global_init(config_path);
69
70 // Application translations
71 translator->load( pref->language );
72 showInfo();
73}
74
75SMPlayer::~SMPlayer() {
76 if (main_window != 0) {
77 deleteGUI();
78 }
79 global_end();
80
81#ifdef LOG_SMPLAYER
82 if (output_log.isOpen()) output_log.close();
83#endif
84}
85
86BaseGui * SMPlayer::gui() {
87 if (main_window == 0) {
88 // Changes to app path, so smplayer can find a relative mplayer path
89 QDir::setCurrent(Paths::appPath());
90 qDebug("SMPlayer::gui: changed working directory to app path");
91 qDebug("SMPlayer::gui: current directory: %s", QDir::currentPath().toUtf8().data());
92
93 main_window = createGUI(gui_to_use);
94
95 if (move_gui) {
96 qDebug("SMPlayer::gui: moving main window to %d %d", gui_position.x(), gui_position.y());
97 main_window->move(gui_position);
98 }
99 if (resize_gui) {
100 qDebug("SMPlayer::gui: resizing main window to %dx%d", gui_size.width(), gui_size.height());
101 main_window->resize(gui_size);
102 }
103 }
104
105 return main_window;
106}
107
108BaseGui * SMPlayer::createGUI(QString gui_name) {
109 BaseGui * gui = 0;
110
111 if (gui_name.toLower() == "minigui")
112 gui = new MiniGui(0);
113 else
114 if (gui_name.toLower() == "mpcgui")
115 gui = new MpcGui(0);
116 else
117 gui = new DefaultGui(0);
118
119 gui->setForceCloseOnFinish(close_at_end);
120 gui->setForceStartInFullscreen(start_in_fullscreen);
121 connect(gui, SIGNAL(quitSolicited()), qApp, SLOT(quit()));
122
123#ifdef GUI_CHANGE_ON_RUNTIME
124 connect(gui, SIGNAL(guiChanged(QString)), this, SLOT(changeGUI(QString)));
125#endif
126
127#if SINGLE_INSTANCE
128 MyApplication * app = MyApplication::instance();
129 connect(app, SIGNAL(messageReceived(const QString&)),
130 gui, SLOT(handleMessageFromOtherInstances(const QString&)));
131 app->setActivationWindow(gui);
132#endif
133
134 return gui;
135}
136
137void SMPlayer::deleteGUI() {
138#ifdef LOG_SMPLAYER
139 allow_to_send_log_to_gui = false;
140#endif
141
142 delete main_window;
143 main_window = 0;
144
145#ifdef LOG_SMPLAYER
146 allow_to_send_log_to_gui = true;
147#endif
148}
149
150#ifdef GUI_CHANGE_ON_RUNTIME
151void SMPlayer::changeGUI(QString new_gui) {
152 qDebug("SMPlayer::changeGUI: '%s'", new_gui.toLatin1().constData());
153
154 deleteGUI();
155
156 main_window = createGUI(new_gui);
157
158 main_window->show();
159}
160#endif
161
162SMPlayer::ExitCode SMPlayer::processArgs(QStringList args) {
163 qDebug("SMPlayer::processArgs: arguments: %d", args.count());
164 for (int n = 0; n < args.count(); n++) {
165 qDebug("SMPlayer::processArgs: %d = %s", n, args[n].toUtf8().data());
166 }
167
168
169 QString action; // Action to be passed to running instance
170 bool show_help = false;
171
172 if (!pref->gui.isEmpty()) gui_to_use = pref->gui;
173 bool add_to_playlist = false;
174
175#ifdef Q_OS_WIN
176 if (args.contains("-uninstall")){
177#if USE_ASSOCIATIONS
178 //Called by uninstaller. Will restore old associations.
179 WinFileAssoc RegAssoc;
180 Extensions exts;
181 QStringList regExts;
182 RegAssoc.GetRegisteredExtensions(exts.multimedia(), regExts);
183 RegAssoc.RestoreFileAssociations(regExts);
184 printf("Restored associations\n");
185#endif
186 return NoError;
187 }
188#endif
189
190 for (int n = 1; n < args.count(); n++) {
191 QString argument = args[n];
192
193 if (argument == "-send-action") {
194 if (n+1 < args.count()) {
195 n++;
196 action = args[n];
197 } else {
198 printf("Error: expected parameter for -send-action\r\n");
199 return ErrorArgument;
200 }
201 }
202 else
203 if (argument == "-actions") {
204 if (n+1 < args.count()) {
205 n++;
206 actions_list = args[n];
207 } else {
208 printf("Error: expected parameter for -actions\r\n");
209 return ErrorArgument;
210 }
211 }
212 else
213 if (argument == "-sub") {
214 if (n+1 < args.count()) {
215 n++;
216 QString file = args[n];
217 if (QFile::exists(file)) {
218 subtitle_file = QFileInfo(file).absoluteFilePath();
219 } else {
220 printf("Error: file '%s' doesn't exists\r\n", file.toUtf8().constData());
221 }
222 } else {
223 printf("Error: expected parameter for -sub\r\n");
224 return ErrorArgument;
225 }
226 }
227 else
228 if (argument == "-pos") {
229 if (n+2 < args.count()) {
230 bool ok_x, ok_y;
231 n++;
232 gui_position.setX( args[n].toInt(&ok_x) );
233 n++;
234 gui_position.setY( args[n].toInt(&ok_y) );
235 if (ok_x && ok_y) move_gui = true;
236 } else {
237 printf("Error: expected parameter for -pos\r\n");
238 return ErrorArgument;
239 }
240 }
241 else
242 if (argument == "-size") {
243 if (n+2 < args.count()) {
244 bool ok_width, ok_height;
245 n++;
246 gui_size.setWidth( args[n].toInt(&ok_width) );
247 n++;
248 gui_size.setHeight( args[n].toInt(&ok_height) );
249 if (ok_width && ok_height) resize_gui = true;
250 } else {
251 printf("Error: expected parameter for -resize\r\n");
252 return ErrorArgument;
253 }
254 }
255 else
256 if ((argument == "--help") || (argument == "-help") ||
257 (argument == "-h") || (argument == "-?") )
258 {
259 show_help = true;
260 }
261 else
262 if (argument == "-close-at-end") {
263 close_at_end = 1;
264 }
265 else
266 if (argument == "-no-close-at-end") {
267 close_at_end = 0;
268 }
269 else
270 if (argument == "-fullscreen") {
271 start_in_fullscreen = 1;
272 }
273 else
274 if (argument == "-no-fullscreen") {
275 start_in_fullscreen = 0;
276 }
277 else
278 if (argument == "-add-to-playlist") {
279 add_to_playlist = true;
280 }
281 else
282 if (argument == "-mini" || argument == "-minigui") {
283 gui_to_use = "MiniGui";
284 }
285 else
286 if (argument == "-mpcgui") {
287 gui_to_use = "MpcGui";
288 }
289 else
290 if (argument == "-defaultgui") {
291 gui_to_use = "DefaultGui";
292 }
293 else {
294 // File
295 #if QT_VERSION >= 0x040600
296 QUrl fUrl = QUrl::fromUserInput(argument);
297 if (fUrl.isValid() && fUrl.scheme().toLower() == "file") {
298 argument = fUrl.toLocalFile();
299 }
300 #endif
301 if (QFile::exists( argument )) {
302 argument = QFileInfo(argument).absoluteFilePath();
303 }
304 files_to_play.append( argument );
305 }
306 }
307
308 if (show_help) {
309 printf("%s\n", CLHelp::help().toLocal8Bit().data());
310 return NoError;
311 }
312
313 qDebug("SMPlayer::processArgs: files_to_play: count: %d", files_to_play.count() );
314 for (int n=0; n < files_to_play.count(); n++) {
315 qDebug("SMPlayer::processArgs: files_to_play[%d]: '%s'", n, files_to_play[n].toUtf8().data());
316 }
317
318#ifdef SINGLE_INSTANCE
319 if (pref->use_single_instance) {
320 // Single instance
321 MyApplication * a = MyApplication::instance();
322 if (a->isRunning()) {
323 a->sendMessage("Hello");
324
325 if (!action.isEmpty()) {
326 a->sendMessage("action " + action);
327 }
328 else {
329 if (!subtitle_file.isEmpty()) {
330 a->sendMessage("load_sub " + subtitle_file);
331 }
332
333 if (!files_to_play.isEmpty()) {
334 /* a->sendMessage("open_file " + files_to_play[0]); */
335 QString command = "open_files";
336 if (add_to_playlist) command = "add_to_playlist";
337 a->sendMessage(command +" "+ files_to_play.join(" <<sep>> "));
338 }
339 }
340
341 return NoError;
342 }
343 }
344#endif
345
346 if (!pref->default_font.isEmpty()) {
347 QFont f;
348 f.fromString(pref->default_font);
349 qApp->setFont(f);
350 }
351
352 return SMPlayer::NoExit;
353}
354
355void SMPlayer::start() {
356 if (!gui()->startHidden() || !files_to_play.isEmpty() ) gui()->show();
357 if (!files_to_play.isEmpty()) {
358 if (!subtitle_file.isEmpty()) gui()->setInitialSubtitle(subtitle_file);
359 gui()->openFiles(files_to_play);
360 }
361
362 if (!actions_list.isEmpty()) {
363 if (files_to_play.isEmpty()) {
364 gui()->runActions(actions_list);
365 } else {
366 gui()->runActionsLater(actions_list);
367 }
368 }
369}
370
371#ifndef PORTABLE_APP
372void SMPlayer::createConfigDirectory() {
373 // Create smplayer config directory
374 if (!QFile::exists(Paths::configPath())) {
375 QDir d;
376 if (!d.mkdir(Paths::configPath())) {
377 qWarning("SMPlayer::createConfigDirectory: can't create %s", Paths::configPath().toUtf8().data());
378 }
379 // Screenshot folder already created in preferences.cpp if Qt >= 4.4
380 #if QT_VERSION < 0x040400
381 QString s = Paths::configPath() + "/screenshots";
382 if (!d.mkdir(s)) {
383 qWarning("SMPlayer::createHomeDirectory: can't create %s", s.toUtf8().data());
384 }
385 #endif
386 }
387}
388#endif
389
390void SMPlayer::showInfo() {
391#ifdef Q_OS_WIN
392 QString win_ver;
393 switch (QSysInfo::WindowsVersion) {
394 case QSysInfo::WV_32s: win_ver = "Windows 3.1"; break;
395 case QSysInfo::WV_95: win_ver = "Windows 95"; break;
396 case QSysInfo::WV_98: win_ver = "Windows 98"; break;
397 case QSysInfo::WV_Me: win_ver = "Windows Me"; break;
398 case QSysInfo::WV_NT: win_ver = "Windows NT"; break;
399 case QSysInfo::WV_2000: win_ver = "Windows 2000"; break;
400 case QSysInfo::WV_XP: win_ver = "Windows XP"; break;
401 case QSysInfo::WV_2003: win_ver = "Windows Server 2003"; break;
402 case QSysInfo::WV_VISTA: win_ver = "Windows Vista"; break;
403 #if QT_VERSION >= 0x040501
404 case QSysInfo::WV_WINDOWS7: win_ver = "Windows 7"; break;
405 #endif
406 default: win_ver = QString("other: %1").arg(QSysInfo::WindowsVersion);
407 }
408#endif
409 QString s = QObject::tr("This is SMPlayer v. %1 running on %2")
410 .arg(smplayerVersion())
411#ifdef Q_OS_LINUX
412 .arg("Linux")
413#else
414#ifdef Q_OS_WIN
415 .arg("Windows ("+win_ver+")")
416#else
417#ifdef Q_OS_OS2
418 .arg("eCS (OS/2)")
419#else
420 .arg("Other OS")
421#endif
422#endif
423#endif
424 ;
425
426 printf("%s\n", s.toLocal8Bit().data() );
427 qDebug("%s", s.toUtf8().data() );
428 qDebug("Compiled with Qt v. %s, using %s", QT_VERSION_STR, qVersion());
429
430 qDebug(" * application path: '%s'", Paths::appPath().toUtf8().data());
431 qDebug(" * data path: '%s'", Paths::dataPath().toUtf8().data());
432 qDebug(" * translation path: '%s'", Paths::translationPath().toUtf8().data());
433 qDebug(" * doc path: '%s'", Paths::docPath().toUtf8().data());
434 qDebug(" * themes path: '%s'", Paths::themesPath().toUtf8().data());
435 qDebug(" * shortcuts path: '%s'", Paths::shortcutsPath().toUtf8().data());
436 qDebug(" * config path: '%s'", Paths::configPath().toUtf8().data());
437 qDebug(" * ini path: '%s'", Paths::iniPath().toUtf8().data());
438 qDebug(" * file for subtitles' styles: '%s'", Paths::subtitleStyleFile().toUtf8().data());
439 qDebug(" * current path: '%s'", QDir::currentPath().toUtf8().data());
440}
441
442#ifdef LOG_SMPLAYER
443QFile SMPlayer::output_log;
444bool SMPlayer::allow_to_send_log_to_gui = false;
445
446void SMPlayer::myMessageOutput( QtMsgType type, const char *msg ) {
447 static QStringList saved_lines;
448 static QString orig_line;
449 static QString line2;
450 static QRegExp rx_log;
451
452 if (pref) {
453 if (!pref->log_smplayer) return;
454 rx_log.setPattern(pref->log_filter);
455 } else {
456 rx_log.setPattern(".*");
457 }
458
459 line2.clear();
460
461 orig_line = QString::fromUtf8(msg);
462
463 switch ( type ) {
464 case QtDebugMsg:
465 if (rx_log.indexIn(orig_line) > -1) {
466 #ifndef NO_DEBUG_ON_CONSOLE
467 fprintf( stderr, "Debug: %s\n", orig_line.toLocal8Bit().data() );
468 #endif
469 line2 = orig_line;
470 }
471 break;
472 case QtWarningMsg:
473 #ifndef NO_DEBUG_ON_CONSOLE
474 fprintf( stderr, "Warning: %s\n", orig_line.toLocal8Bit().data() );
475 #endif
476 line2 = "WARNING: " + orig_line;
477 break;
478 case QtFatalMsg:
479 #ifndef NO_DEBUG_ON_CONSOLE
480 fprintf( stderr, "Fatal: %s\n", orig_line.toLocal8Bit().data() );
481 #endif
482 line2 = "FATAL: " + orig_line;
483 abort(); // deliberately core dump
484 case QtCriticalMsg:
485 #ifndef NO_DEBUG_ON_CONSOLE
486 fprintf( stderr, "Critical: %s\n", orig_line.toLocal8Bit().data() );
487 #endif
488 line2 = "CRITICAL: " + orig_line;
489 break;
490 }
491
492 if (line2.isEmpty()) return;
493
494 line2 = "["+ QTime::currentTime().toString("hh:mm:ss:zzz") +"] "+ line2;
495
496 if (allow_to_send_log_to_gui && main_window) {
497 if (!saved_lines.isEmpty()) {
498 // Send saved lines first
499 for (int n=0; n < saved_lines.count(); n++) {
500 main_window->recordSmplayerLog(saved_lines[n]);
501 }
502 saved_lines.clear();
503 }
504 main_window->recordSmplayerLog(line2);
505 } else {
506 // GUI is not created yet, save lines for later
507 saved_lines.append(line2);
508 /* printf("SMPlayer::myMessageOutput: no gui\n"); */
509 }
510
511 if (pref) {
512 if (pref->save_smplayer_log) {
513 // Save log to file
514 if (!output_log.isOpen()) {
515 // FIXME: the config path may not be initialized if USE_LOCKS is not defined
516 output_log.setFileName( Paths::configPath() + "/smplayer_log.txt" );
517 output_log.open(QIODevice::WriteOnly);
518 }
519 if (output_log.isOpen()) {
520 QString l = line2 + "\r\n";
521 output_log.write(l.toUtf8().constData());
522 output_log.flush();
523 }
524 }
525 }
526}
527#endif
528
529/*
530void myMessageOutput( QtMsgType type, const char *msg ) {
531 static QString orig_line;
532 orig_line = QString::fromUtf8(msg);
533
534 switch ( type ) {
535 case QtDebugMsg:
536 #ifndef NO_DEBUG_ON_CONSOLE
537 fprintf( stderr, "Debug: %s\n", orig_line.toLocal8Bit().data() );
538 #endif
539 break;
540
541 case QtWarningMsg:
542 #ifndef NO_DEBUG_ON_CONSOLE
543 fprintf( stderr, "Warning: %s\n", orig_line.toLocal8Bit().data() );
544 #endif
545 break;
546
547 case QtCriticalMsg:
548 #ifndef NO_DEBUG_ON_CONSOLE
549 fprintf( stderr, "Critical: %s\n", orig_line.toLocal8Bit().data() );
550 #endif
551 break;
552
553 case QtFatalMsg:
554 #ifndef NO_DEBUG_ON_CONSOLE
555 fprintf( stderr, "Fatal: %s\n", orig_line.toLocal8Bit().data() );
556 #endif
557 abort(); // deliberately core dump
558 }
559}
560*/
561
562#include "moc_smplayer.cpp"
Note: See TracBrowser for help on using the repository browser.