1 /*
2  * soundkonverter.cpp
3  *
4  * Copyright (C) 2007 Daniel Faust <hessijames@gmail.com>
5  */
6 #include "soundkonverter.h"
7 #include "soundkonverterview.h"
8 #include "global.h"
9 #include "config.h"
10 #include "configdialog/configdialog.h"
11 #include "logger.h"
12 #include "logviewer.h"
13 #include "replaygainscanner/replaygainscanner.h"
14 #include "aboutplugins.h"
15 
16 #include <taglib.h>
17 
18 #include <KActionCollection>
19 #include <KApplication>
20 #include <KActionMenu>
21 #include <KLocale>
22 #include <KToolBar>
23 #include <KIcon>
24 #include <KStandardDirs>
25 #include <KMenu>
26 #include <KMessageBox>
27 #include <QDir>
28 
29 #include <KStatusNotifierItem>
30 
soundKonverter()31 soundKonverter::soundKonverter()
32     : KXmlGuiWindow(),
33       logViewer( 0 ),
34       systemTray( 0 ),
35       autoclose( false )
36 {
37     // accept dnd
38     setAcceptDrops(true);
39 
40     const int fontHeight = QFontMetrics(QApplication::font()).boundingRect("M").size().height();
41 
42     logger = new Logger( this );
43     logger->log( 1000, i18n("This is soundKonverter %1").arg(SOUNDKONVERTER_VERSION_STRING) );
44 
45     logger->log( 1000, "\n" + i18n("Compiled with TagLib %1.%2.%3").arg(TAGLIB_MAJOR_VERSION).arg(TAGLIB_MINOR_VERSION).arg(TAGLIB_PATCH_VERSION) );
46 
47     config = new Config( logger, this );
48     config->load();
49 
50     m_view = new soundKonverterView( logger, config, cdManager, this );
51     connect( m_view, SIGNAL(signalConversionStarted()), this, SLOT(conversionStarted()) );
52     connect( m_view, SIGNAL(signalConversionStopped(bool)), this, SLOT(conversionStopped(bool)) );
53     connect( m_view, SIGNAL(progressChanged(const QString&)), this, SLOT(progressChanged(const QString&)) );
54     connect( m_view, SIGNAL(showLog(int)), this, SLOT(showLogViewer(int)) );
55 
56     // tell the KXmlGuiWindow that this is indeed the main widget
57     setCentralWidget( m_view );
58 
59     // then, setup our actions
60     setupActions();
61 
62     // a call to KXmlGuiWindow::setupGUI() populates the GUI
63     // with actions, using KXMLGUI.
64     // It also applies the saved mainwindow settings, if any, and ask the
65     // mainwindow to automatically save settings if changed: window size,
66     // toolbar position, icon size, etc.
67     setupGUI( QSize(70*fontHeight,45*fontHeight), ToolBar | Keys | Save | Create );
68 }
69 
~soundKonverter()70 soundKonverter::~soundKonverter()
71 {
72     if( logViewer )
73         delete logViewer;
74 
75     if( replayGainScanner )
76         delete replayGainScanner.data();
77 
78     if( systemTray )
79         delete systemTray;
80 }
81 
saveProperties(KConfigGroup & configGroup)82 void soundKonverter::saveProperties( KConfigGroup& configGroup )
83 {
84     Q_UNUSED(configGroup)
85 
86     m_view->killConversion();
87 
88     m_view->saveFileList( false );
89 }
90 
showSystemTray()91 void soundKonverter::showSystemTray()
92 {
93     systemTray = new KStatusNotifierItem( this );
94     systemTray->setCategory( KStatusNotifierItem::ApplicationStatus );
95     systemTray->setStatus( KStatusNotifierItem::Active );
96     systemTray->setIconByName( "soundkonverter" );
97     systemTray->setToolTip( "soundkonverter", i18n("Waiting"), "" );
98 }
99 
addConvertFiles(const KUrl::List & urls,const QString & profile,const QString & format,const QString & directory,const QString & notifyCommand)100 void soundKonverter::addConvertFiles( const KUrl::List& urls, const QString& profile, const QString& format, const QString& directory, const QString& notifyCommand )
101 {
102     m_view->addConvertFiles( urls, profile, format, directory, notifyCommand );
103 }
104 
addReplayGainFiles(const KUrl::List & urls)105 void soundKonverter::addReplayGainFiles( const KUrl::List& urls )
106 {
107     showReplayGainScanner();
108     replayGainScanner.data()->addFiles( urls );
109 }
110 
ripCd(const QString & device,const QString & profile,const QString & format,const QString & directory,const QString & notifyCommand)111 bool soundKonverter::ripCd( const QString& device, const QString& profile, const QString& format, const QString& directory, const QString& notifyCommand )
112 {
113     return m_view->showCdDialog( device != "auto" ? device : "", profile, format, directory, notifyCommand );
114 }
115 
setupActions()116 void soundKonverter::setupActions()
117 {
118     KStandardAction::quit( this, SLOT(close()), actionCollection() );
119     KStandardAction::preferences( this, SLOT(showConfigDialog()), actionCollection() );
120 
121     QAction *logviewer = actionCollection()->addAction("logviewer");
122     logviewer->setText(i18n("View logs..."));
123     logviewer->setIcon(KIcon("view-list-text"));
124     connect( logviewer, SIGNAL(triggered()), this, SLOT(showLogViewer()) );
125 
126     QAction *replaygainscanner = actionCollection()->addAction("replaygainscanner");
127     replaygainscanner->setText(i18n("Replay Gain tool..."));
128     replaygainscanner->setIcon(KIcon("soundkonverter-replaygain"));
129     connect( replaygainscanner, SIGNAL(triggered()), this, SLOT(showReplayGainScanner()) );
130 
131     QAction *aboutplugins = actionCollection()->addAction("aboutplugins");
132     aboutplugins->setText(i18n("About plugins..."));
133     aboutplugins->setIcon(KIcon("preferences-plugin"));
134     connect( aboutplugins, SIGNAL(triggered()), this, SLOT(showAboutPlugins()) );
135 
136     QAction *add_files = actionCollection()->addAction("add_files");
137     add_files->setText(i18n("Add files..."));
138     add_files->setIcon(KIcon("audio-x-generic"));
139     connect( add_files, SIGNAL(triggered()), m_view, SLOT(showFileDialog()) );
140 
141     QAction *add_folder = actionCollection()->addAction("add_folder");
142     add_folder->setText(i18n("Add folder..."));
143     add_folder->setIcon(KIcon("folder"));
144     connect( add_folder, SIGNAL(triggered()), m_view, SLOT(showDirDialog()) );
145 
146     QAction *add_audiocd = actionCollection()->addAction("add_audiocd");
147     add_audiocd->setText(i18n("Add CD tracks..."));
148     add_audiocd->setIcon(KIcon("media-optical-audio"));
149     connect( add_audiocd, SIGNAL(triggered()), m_view, SLOT(showCdDialog()) );
150 
151     QAction *add_url = actionCollection()->addAction("add_url");
152     add_url->setText(i18n("Add url..."));
153     add_url->setIcon(KIcon("network-workgroup"));
154     connect( add_url, SIGNAL(triggered()), m_view, SLOT(showUrlDialog()) );
155 
156     QAction *add_playlist = actionCollection()->addAction("add_playlist");
157     add_playlist->setText(i18n("Add playlist..."));
158     add_playlist->setIcon(KIcon("view-media-playlist"));
159     connect( add_playlist, SIGNAL(triggered()), m_view, SLOT(showPlaylistDialog()) );
160 
161     QAction *load = actionCollection()->addAction("load");
162     load->setText(i18n("Load file list"));
163     load->setIcon(KIcon("document-open"));
164     connect( load, SIGNAL(triggered()), m_view, SLOT(loadFileList()) );
165 
166     QAction *save = actionCollection()->addAction("save");
167     save->setText(i18n("Save file list"));
168     save->setIcon(KIcon("document-save"));
169     connect( save, SIGNAL(triggered()), m_view, SLOT(saveFileList()) );
170 
171     actionCollection()->addAction("start", m_view->start());
172     actionCollection()->addAction("stop_menu", m_view->stopMenu());
173 }
174 
showConfigDialog()175 void soundKonverter::showConfigDialog()
176 {
177     ConfigDialog *dialog = new ConfigDialog( config, this/*, ConfigDialog::Page(configStartPage)*/ );
178     connect( dialog, SIGNAL(updateFileList()), m_view, SLOT(updateFileList()) );
179 
180     dialog->resize( size() );
181     dialog->exec();
182 
183     delete dialog;
184 }
185 
showLogViewer(const int logId)186 void soundKonverter::showLogViewer( const int logId )
187 {
188     if( !logViewer )
189         logViewer = new LogViewer( logger, 0 );
190 
191     if( logId )
192         logViewer->showLog( logId );
193 
194     logViewer->show();
195     logViewer->raise();
196 }
197 
showReplayGainScanner()198 void soundKonverter::showReplayGainScanner()
199 {
200     if( !replayGainScanner )
201     {
202         replayGainScanner = new ReplayGainScanner( config, logger, !isVisible(), 0 );
203         connect( replayGainScanner.data(), SIGNAL(finished()), this, SLOT(replayGainScannerClosed()) );
204         connect( replayGainScanner.data(), SIGNAL(showMainWindow()), this, SLOT(showMainWindow()) );
205     }
206 
207     replayGainScanner.data()->setAttribute( Qt::WA_DeleteOnClose );
208 
209     replayGainScanner.data()->show();
210     replayGainScanner.data()->raise();
211     replayGainScanner.data()->activateWindow();
212 }
213 
replayGainScannerClosed()214 void soundKonverter::replayGainScannerClosed()
215 {
216     if( !isVisible() )
217         KApplication::kApplication()->quit();
218 }
219 
showMainWindow()220 void soundKonverter::showMainWindow()
221 {
222     show();
223 }
224 
showAboutPlugins()225 void soundKonverter::showAboutPlugins()
226 {
227     AboutPlugins *dialog = new AboutPlugins( config, this );
228     dialog->exec();
229     dialog->deleteLater();
230 }
231 
startConversion()232 void soundKonverter::startConversion()
233 {
234     m_view->startConversion();
235 }
236 
loadAutosaveFileList()237 void soundKonverter::loadAutosaveFileList()
238 {
239     m_view->loadAutosaveFileList();
240 }
241 
loadFileList(const QString & fileListPath)242 void soundKonverter::loadFileList(const QString& fileListPath)
243 {
244     m_view->loadFileList(fileListPath);
245 }
246 
startupChecks()247 void soundKonverter::startupChecks()
248 {
249     // check if codec plugins could be loaded
250     if( config->pluginLoader()->getAllCodecPlugins().count() == 0 )
251     {
252         KMessageBox::error(this, i18n("No codec plugins could be loaded. Without codec plugins soundKonverter can't work.\nThis problem can have two causes:\n1. You just installed soundKonverter and the KDE System Configuration Cache is not up-to-date, yet.\nIn this case, run kbuildsycoca4 and restart soundKonverter to fix the problem.\n2. Your installation is broken.\nIn this case try reinstalling soundKonverter."));
253     }
254 
255     // remove old KDE4 action menus created by soundKonverter 0.3 - don't change the paths, it's what soundKonverter 0.3 used
256     if( config->data.app.configVersion < 1001 )
257     {
258         if( QFile::exists(QDir::homePath()+"/.kde4/share/kde4/services/ServiceMenus/convert_with_soundkonverter.desktop") )
259         {
260             QFile::remove(QDir::homePath()+"/.kde4/share/kde4/services/ServiceMenus/convert_with_soundkonverter.desktop");
261             logger->log( 1000, i18n("Removing old file: %1").arg(QDir::homePath()+"/.kde4/share/kde4/services/ServiceMenus/convert_with_soundkonverter.desktop") );
262         }
263         if( QFile::exists(QDir::homePath()+"/.kde4/share/kde4/services/ServiceMenus/add_replaygain_with_soundkonverter.desktop") )
264         {
265             QFile::remove(QDir::homePath()+"/.kde4/share/kde4/services/ServiceMenus/add_replaygain_with_soundkonverter.desktop");
266             logger->log( 1000, i18n("Removing old file: %1").arg(QDir::homePath()+"/.kde4/share/kde4/services/ServiceMenus/add_replaygain_with_soundkonverter.desktop") );
267         }
268     }
269 
270     // clean up log directory
271     QDir dir( KStandardDirs::locateLocal("data","soundkonverter/log/") );
272     dir.setFilter( QDir::Files | QDir::Writable );
273 
274     QStringList list = dir.entryList();
275 
276     for( QStringList::Iterator it = list.begin(); it != list.end(); ++it )
277     {
278         if( *it != "1000.log" && (*it).endsWith(".log") )
279         {
280             QFile::remove( dir.absolutePath() + "/" + (*it) );
281             logger->log( 1000, i18n("Removing old file: %1").arg(dir.absolutePath()+"/"+(*it)) );
282         }
283     }
284 
285     // check if new backends got installed and the backend settings can be optimized
286     QList<CodecOptimizations::Optimization> optimizationList = config->getOptimizations();
287     if( !optimizationList.isEmpty() )
288     {
289         CodecOptimizations *optimizationsDialog = new CodecOptimizations( optimizationList, this );
290         connect( optimizationsDialog, SIGNAL(solutions(const QList<CodecOptimizations::Optimization>&)), config, SLOT(doOptimizations(const QList<CodecOptimizations::Optimization>&)) );
291         optimizationsDialog->open();
292     }
293 }
294 
conversionStarted()295 void soundKonverter::conversionStarted()
296 {
297     if( systemTray )
298     {
299         systemTray->setToolTip( "soundkonverter", i18n("Converting") + ": 0%", "" );
300     }
301 }
302 
conversionStopped(bool failed)303 void soundKonverter::conversionStopped( bool failed )
304 {
305     if( autoclose && !failed /*&& !m_view->isVisible()*/ )
306         KApplication::kApplication()->quit(); // close app on conversion stop unless the conversion was stopped by the user or the window is shown
307 
308     if( systemTray )
309     {
310         systemTray->setToolTip( "soundkonverter", i18n("Finished"), "" );
311     }
312 }
313 
progressChanged(const QString & progress)314 void soundKonverter::progressChanged( const QString& progress )
315 {
316     setWindowTitle( progress + " - soundKonverter" );
317 
318     if( systemTray )
319     {
320         #if KDE_IS_VERSION(4,4,0)
321             systemTray->setToolTip( "soundkonverter", i18n("Converting") + ": " + progress, "" );
322         #else
323             systemTray->setToolTip( i18n("Converting") + ": " + progress );
324         #endif
325     }
326 }
327 
328 
329 #include "soundkonverter.moc"
330