K3b – CD/DVD burning application
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

1631 lines
50 KiB

  1. /*
  2. *
  3. * $Id: k3b.cpp 642063 2007-03-13 09:40:13Z trueg $
  4. * Copyright (C) 1998-2007 Sebastian Trueg <trueg@k3b.org>
  5. *
  6. * This file is part of the K3b project.
  7. * Copyright (C) 1998-2007 Sebastian Trueg <trueg@k3b.org>
  8. *
  9. * This program is free software; you can redistribute it and/or modify
  10. * it under the terms of the GNU General Public License as published by
  11. * the Free Software Foundation; either version 2 of the License, or
  12. * (at your option) any later version.
  13. * See the file "COPYING" for the exact licensing terms.
  14. */
  15. #include <config.h>
  16. // include files for QT
  17. #include <tqdir.h>
  18. #include <tqfile.h>
  19. #include <tqfileinfo.h>
  20. #include <tqlayout.h>
  21. #include <tqwhatsthis.h>
  22. #include <tqtooltip.h>
  23. #include <tqtoolbutton.h>
  24. #include <tqstring.h>
  25. #include <tqsplitter.h>
  26. #include <tqevent.h>
  27. #include <tqvaluelist.h>
  28. #include <tqfont.h>
  29. #include <tqpalette.h>
  30. #include <tqwidgetstack.h>
  31. #include <tqtimer.h>
  32. #include <kdockwidget.h>
  33. #include <kkeydialog.h>
  34. // include files for KDE
  35. #include <kiconloader.h>
  36. #include <tdemessagebox.h>
  37. #include <tdefiledialog.h>
  38. #include <tdemenubar.h>
  39. #include <tdelocale.h>
  40. #include <tdeconfig.h>
  41. #include <kstdaction.h>
  42. #include <klineeditdlg.h>
  43. #include <kstandarddirs.h>
  44. #include <kprocess.h>
  45. #include <kurl.h>
  46. #include <kurllabel.h>
  47. #include <tdetoolbar.h>
  48. #include <kstatusbar.h>
  49. #include <tdeglobalsettings.h>
  50. #include <kdialog.h>
  51. #include <kedittoolbar.h>
  52. #include <ksystemtray.h>
  53. #include <tdeaboutdata.h>
  54. #include <ktip.h>
  55. #include <kxmlguifactory.h>
  56. #include <kstdguiitem.h>
  57. #include <tdeio/global.h>
  58. #include <tdeio/netaccess.h>
  59. #include <tderecentdocument.h>
  60. #include <stdlib.h>
  61. // application specific includes
  62. #include "k3b.h"
  63. #include "k3bapplication.h"
  64. #include <k3bglobals.h>
  65. #include "k3bview.h"
  66. #include "k3bdirview.h"
  67. #include <k3baudiodoc.h>
  68. #include "k3baudioview.h"
  69. #include "k3bappdevicemanager.h"
  70. #include "k3baudiotrackdialog.h"
  71. #include "option/k3boptiondialog.h"
  72. #include "k3bprojectburndialog.h"
  73. #include <k3bdatadoc.h>
  74. #include "k3bdataview.h"
  75. #include <k3bdvddoc.h>
  76. #include "k3bdvdview.h"
  77. #include <k3bvideodvddoc.h>
  78. #include "k3bvideodvdview.h"
  79. #include <k3bmixeddoc.h>
  80. #include "k3bmixedview.h"
  81. #include <k3bvcddoc.h>
  82. #include "k3bvcdview.h"
  83. #include <k3bmovixdoc.h>
  84. #include "k3bmovixview.h"
  85. #include <k3bmovixdvddoc.h>
  86. #include "k3bmovixdvdview.h"
  87. #include "misc/k3bblankingdialog.h"
  88. #include "misc/k3bcdimagewritingdialog.h"
  89. #include "misc/k3bisoimagewritingdialog.h"
  90. #include <k3bexternalbinmanager.h>
  91. #include "k3bprojecttabwidget.h"
  92. #include "misc/k3bcdcopydialog.h"
  93. #include "k3btempdirselectionwidget.h"
  94. #include "k3bstatusbarmanager.h"
  95. #include "k3bfiletreecombobox.h"
  96. #include "k3bfiletreeview.h"
  97. #include "k3bsidepanel.h"
  98. #include "k3bstdguiitems.h"
  99. #include "misc/k3bdvdformattingdialog.h"
  100. #include "misc/k3bdvdcopydialog.h"
  101. //#include "dvdcopy/k3bvideodvdcopydialog.h"
  102. #include "k3bprojectmanager.h"
  103. #include "k3bwelcomewidget.h"
  104. #include <k3bpluginmanager.h>
  105. #include <k3bplugin.h>
  106. #include "k3bsystemproblemdialog.h"
  107. #include <k3baudiodecoder.h>
  108. #include <k3bthememanager.h>
  109. #include <k3biso9660.h>
  110. #include <k3bcuefileparser.h>
  111. #include <k3bdeviceselectiondialog.h>
  112. #include <k3bjob.h>
  113. #include <k3bsignalwaiter.h>
  114. #include "k3bmediaselectiondialog.h"
  115. #include "k3bmediacache.h"
  116. #include "k3bmedium.h"
  117. #include "projects/k3bdatasessionimportdialog.h"
  118. #include "k3bpassivepopup.h"
  119. #include "k3bthemedheader.h"
  120. #include <k3baudioserver.h>
  121. class K3bMainWindow::Private
  122. {
  123. public:
  124. K3bDoc* lastDoc;
  125. TQWidgetStack* documentStack;
  126. K3bWelcomeWidget* welcomeWidget;
  127. TQWidget* documentHull;
  128. TQLabel* leftDocPicLabel;
  129. TQLabel* centerDocLabel;
  130. TQLabel* rightDocPicLabel;
  131. };
  132. K3bMainWindow::K3bMainWindow()
  133. : DockMainWindow(0,"K3bMainwindow")
  134. {
  135. //setup splitter behavior
  136. manager()->setSplitterHighResolution(true);
  137. manager()->setSplitterOpaqueResize(true);
  138. manager()->setSplitterKeepSize(true);
  139. d = new Private;
  140. d->lastDoc = 0;
  141. setPlainCaption( i18n("K3b - The CD and DVD Kreator") );
  142. m_config = kapp->config();
  143. ///////////////////////////////////////////////////////////////////
  144. // call inits to invoke all other construction parts
  145. initActions();
  146. initView();
  147. initStatusBar();
  148. createGUI(0L);
  149. // we need the actions for the welcomewidget
  150. d->welcomeWidget->loadConfig( config() );
  151. // fill the tabs action menu
  152. m_documentTab->insertAction( actionFileSave );
  153. m_documentTab->insertAction( actionFileSaveAs );
  154. m_documentTab->insertAction( actionFileClose );
  155. // /////////////////////////////////////////////////////////////////
  156. // disable actions at startup
  157. slotStateChanged( "state_project_active", KXMLGUIClient::StateReverse );
  158. connect( k3bappcore->projectManager(), TQT_SIGNAL(newProject(K3bDoc*)), TQT_TQOBJECT(this), TQT_SLOT(createClient(K3bDoc*)) );
  159. connect( k3bcore->deviceManager(), TQT_SIGNAL(changed()), TQT_TQOBJECT(this), TQT_SLOT(slotCheckSystemTimed()) );
  160. connect( K3bAudioServer::instance(), TQT_SIGNAL(error(const TQString&)), TQT_TQOBJECT(this), TQT_SLOT(slotAudioServerError(const TQString&)) );
  161. // FIXME: now make sure the welcome screen is displayed completely
  162. resize( 780, 550 );
  163. // getMainDockWidget()->resize( getMainDockWidget()->size().expandedTo( d->welcomeWidget->sizeHint() ) );
  164. // m_dirTreeDock->resize( TQSize( m_dirTreeDock->sizeHint().width(), m_dirTreeDock->height() ) );
  165. readOptions();
  166. }
  167. K3bMainWindow::~K3bMainWindow()
  168. {
  169. delete mainDock;
  170. delete m_contentsDock;
  171. delete d;
  172. }
  173. void K3bMainWindow::showEvent( TQShowEvent* e )
  174. {
  175. slotCheckDockWidgetStatus();
  176. KDockMainWindow::showEvent( e );
  177. }
  178. void K3bMainWindow::initActions()
  179. {
  180. // merge in the device actions from the device manager
  181. // operator+= is deprecated but I know no other way to do this. Why does the KDE app framework
  182. // need to have all actions in the mainwindow's actioncollection anyway (or am I just to stupid to
  183. // see the correct solution?)
  184. *actionCollection() += *k3bappcore->appDeviceManager()->actionCollection();
  185. actionFileOpen = KStdAction::open(TQT_TQOBJECT(this), TQT_SLOT(slotFileOpen()), actionCollection());
  186. actionFileOpenRecent = KStdAction::openRecent(TQT_TQOBJECT(this), TQT_SLOT(slotFileOpenRecent(const KURL&)), actionCollection());
  187. actionFileSave = KStdAction::save(TQT_TQOBJECT(this), TQT_SLOT(slotFileSave()), actionCollection());
  188. actionFileSaveAs = KStdAction::saveAs(TQT_TQOBJECT(this), TQT_SLOT(slotFileSaveAs()), actionCollection());
  189. actionFileSaveAll = new TDEAction( i18n("Save All"), "save_all", 0, TQT_TQOBJECT(this), TQT_SLOT(slotFileSaveAll()),
  190. actionCollection(), "file_save_all" );
  191. actionFileClose = KStdAction::close(TQT_TQOBJECT(this), TQT_SLOT(slotFileClose()), actionCollection());
  192. actionFileCloseAll = new TDEAction( i18n("Close All"), 0, 0, TQT_TQOBJECT(this), TQT_SLOT(slotFileCloseAll()),
  193. actionCollection(), "file_close_all" );
  194. actionFileQuit = KStdAction::quit(TQT_TQOBJECT(this), TQT_SLOT(slotFileQuit()), actionCollection());
  195. actionViewStatusBar = KStdAction::showStatusbar(TQT_TQOBJECT(this), TQT_SLOT(slotViewStatusBar()), actionCollection());
  196. actionSettingsConfigure = KStdAction::preferences(TQT_TQOBJECT(this), TQT_SLOT(slotSettingsConfigure()), actionCollection() );
  197. // the tip action
  198. (void)KStdAction::tipOfDay(TQT_TQOBJECT(this), TQT_SLOT(slotShowTips()), actionCollection() );
  199. (void)KStdAction::keyBindings( TQT_TQOBJECT(this), TQT_SLOT( slotConfigureKeys() ), actionCollection() );
  200. KStdAction::configureToolbars(TQT_TQOBJECT(this), TQT_SLOT(slotEditToolbars()), actionCollection());
  201. setStandardToolBarMenuEnabled(true);
  202. KStdAction::showMenubar( TQT_TQOBJECT(this), TQT_SLOT(slotShowMenuBar()), actionCollection() );
  203. actionFileNewMenu = new TDEActionMenu( i18n("&New Project"), "document-new", actionCollection(), "file_new" );
  204. actionFileNewAudio = new TDEAction(i18n("New &Audio CD Project"), "audiocd", 0, TQT_TQOBJECT(this), TQT_SLOT(slotNewAudioDoc()),
  205. actionCollection(), "file_new_audio");
  206. actionFileNewData = new TDEAction(i18n("New Data &CD Project"), "datacd", 0, TQT_TQOBJECT(this), TQT_SLOT(slotNewDataDoc()),
  207. actionCollection(), "file_new_data");
  208. actionFileNewMixed = new TDEAction(i18n("New &Mixed Mode CD Project"), "mixedcd", 0, TQT_TQOBJECT(this), TQT_SLOT(slotNewMixedDoc()),
  209. actionCollection(), "file_new_mixed");
  210. actionFileNewVcd = new TDEAction(i18n("New &Video CD Project"), "videocd", 0, TQT_TQOBJECT(this), TQT_SLOT(slotNewVcdDoc()),
  211. actionCollection(), "file_new_vcd");
  212. actionFileNewMovix = new TDEAction(i18n("New &eMovix CD Project"), "emovix", 0, TQT_TQOBJECT(this), TQT_SLOT(slotNewMovixDoc()),
  213. actionCollection(), "file_new_movix");
  214. actionFileNewMovixDvd = new TDEAction(i18n("New &eMovix DVD Project"), "emovix", 0, TQT_TQOBJECT(this), TQT_SLOT(slotNewMovixDvdDoc()),
  215. actionCollection(), "file_new_movix_dvd");
  216. actionFileNewDvd = new TDEAction(i18n("New Data &DVD Project"), "datadvd", 0, TQT_TQOBJECT(this), TQT_SLOT(slotNewDvdDoc()),
  217. actionCollection(), "file_new_dvd");
  218. actionFileNewVideoDvd = new TDEAction(i18n("New V&ideo DVD Project"), "videodvd", 0, TQT_TQOBJECT(this), TQT_SLOT(slotNewVideoDvdDoc()),
  219. actionCollection(), "file_new_video_dvd");
  220. actionFileContinueMultisession = new TDEAction( i18n("Continue Multisession Project"), "datacd", 0, TQT_TQOBJECT(this), TQT_SLOT(slotContinueMultisession()),
  221. actionCollection(), "file_continue_multisession" );
  222. actionFileNewMenu->setDelayed( false );
  223. actionFileNewMenu->insert( actionFileNewData );
  224. actionFileNewMenu->insert( actionFileNewDvd );
  225. actionFileNewMenu->insert( actionFileContinueMultisession );
  226. actionFileNewMenu->insert( new TDEActionSeparator( TQT_TQOBJECT(this) ) );
  227. actionFileNewMenu->insert( actionFileNewAudio );
  228. actionFileNewMenu->insert( new TDEActionSeparator( TQT_TQOBJECT(this) ) );
  229. actionFileNewMenu->insert( actionFileNewMixed );
  230. actionFileNewMenu->insert( new TDEActionSeparator( TQT_TQOBJECT(this) ) );
  231. actionFileNewMenu->insert( actionFileNewVcd );
  232. actionFileNewMenu->insert( actionFileNewVideoDvd );
  233. actionFileNewMenu->insert( new TDEActionSeparator( TQT_TQOBJECT(this) ) );
  234. actionFileNewMenu->insert( actionFileNewMovix );
  235. actionFileNewMenu->insert( actionFileNewMovixDvd );
  236. actionProjectAddFiles = new TDEAction( i18n("&Add Files..."), "document-new", 0, TQT_TQOBJECT(this), TQT_SLOT(slotProjectAddFiles()),
  237. actionCollection(), "project_add_files");
  238. TDEAction* actionClearProject = new TDEAction( i18n("&Clear Project"), TQApplication::reverseLayout() ? "clear_left" : "locationbar_erase", 0,
  239. TQT_TQOBJECT(this), TQT_SLOT(slotClearProject()), actionCollection(), "project_clear_project" );
  240. actionViewDirTreeView = new TDEToggleAction(i18n("Show Directories"), 0, TQT_TQOBJECT(this), TQT_SLOT(slotShowDirTreeView()),
  241. actionCollection(), "view_dir_tree");
  242. actionViewContentsView = new TDEToggleAction(i18n("Show Contents"), 0, TQT_TQOBJECT(this), TQT_SLOT(slotShowContentsView()),
  243. actionCollection(), "view_contents");
  244. actionViewDocumentHeader = new TDEToggleAction(i18n("Show Document Header"), 0, TQT_TQOBJECT(this), TQT_SLOT(slotViewDocumentHeader()),
  245. actionCollection(), "view_document_header");
  246. actionToolsBlankCdrw = new TDEAction( i18n("&Erase CD-RW..."), "erasecd", 0, TQT_TQOBJECT(this), TQT_SLOT(slotBlankCdrw()),
  247. actionCollection(), "tools_blank_cdrw" );
  248. TDEAction* actionToolsFormatDVD = new TDEAction( i18n("&Format DVD%1RW...").arg("±"), "formatdvd", 0, TQT_TQOBJECT(this),
  249. TQT_SLOT(slotFormatDvd()), actionCollection(), "tools_format_dvd" );
  250. actionToolsWriteCdImage = new TDEAction(i18n("&Burn CD Image..."), "burn_cdimage", 0, TQT_TQOBJECT(this), TQT_SLOT(slotWriteCdImage()),
  251. actionCollection(), "tools_write_cd_image" );
  252. TDEAction* actionToolsWriteDvdImage = new TDEAction(i18n("&Burn DVD ISO Image..."), "burn_dvdimage", 0, TQT_TQOBJECT(this), TQT_SLOT(slotWriteDvdIsoImage()),
  253. actionCollection(), "tools_write_dvd_iso" );
  254. actionCdCopy = new TDEAction(i18n("&Copy CD..."), "cdcopy", 0, TQT_TQOBJECT(this), TQT_SLOT(slotCdCopy()),
  255. actionCollection(), "tools_copy_cd" );
  256. TDEAction* actionToolsDvdCopy = new TDEAction(i18n("Copy &DVD..."), "dvdcopy", 0, TQT_TQOBJECT(this), TQT_SLOT(slotDvdCopy()),
  257. actionCollection(), "tools_copy_dvd" );
  258. actionToolsCddaRip = new TDEAction( i18n("Rip Audio CD..."), "cddarip", 0, TQT_TQOBJECT(this), TQT_SLOT(slotCddaRip()),
  259. actionCollection(), "tools_cdda_rip" );
  260. actionToolsVideoDvdRip = new TDEAction( i18n("Rip Video DVD..."), "videodvd", 0, TQT_TQOBJECT(this), TQT_SLOT(slotVideoDvdRip()),
  261. actionCollection(), "tools_videodvd_rip" );
  262. actionToolsVideoCdRip = new TDEAction( i18n("Rip Video CD..."), "videocd", 0, TQT_TQOBJECT(this), TQT_SLOT(slotVideoCdRip()),
  263. actionCollection(), "tools_videocd_rip" );
  264. (void)new TDEAction( i18n("System Check"), 0, 0, TQT_TQOBJECT(this), TQT_SLOT(slotCheckSystem()),
  265. actionCollection(), "help_check_system" );
  266. #ifdef HAVE_K3BSETUP
  267. actionSettingsK3bSetup = new TDEAction(i18n("&Setup System Permissions..."), "configure", 0, TQT_TQOBJECT(this), TQT_SLOT(slotK3bSetup()),
  268. actionCollection(), "settings_k3bsetup" );
  269. #endif
  270. #ifdef K3B_DEBUG
  271. (void)new TDEAction( "Test Media Selection ComboBox", 0, 0, TQT_TQOBJECT(this),
  272. TQT_SLOT(slotMediaSelectionTester()), actionCollection(),
  273. "test_media_selection" );
  274. #endif
  275. actionFileNewMenu->setToolTip(i18n("Creates a new project"));
  276. actionFileNewData->setToolTip( i18n("Creates a new data CD project") );
  277. actionFileNewAudio->setToolTip( i18n("Creates a new audio CD project") );
  278. actionFileNewMovixDvd->setToolTip( i18n("Creates a new eMovix DVD project") );
  279. actionFileNewDvd->setToolTip( i18n("Creates a new data DVD project") );
  280. actionFileNewMovix->setToolTip( i18n("Creates a new eMovix CD project") );
  281. actionFileNewVcd->setToolTip( i18n("Creates a new Video CD project") );
  282. actionToolsBlankCdrw->setToolTip( i18n("Open the CD-RW erasing dialog") );
  283. actionToolsFormatDVD->setToolTip( i18n("Open the DVD%1RW formatting dialog").arg("±") );
  284. actionCdCopy->setToolTip( i18n("Open the CD copy dialog") );
  285. actionToolsWriteCdImage->setToolTip( i18n("Write an Iso9660, cue/bin, or cdrecord clone image to CD") );
  286. actionToolsWriteDvdImage->setToolTip( i18n("Write an Iso9660 image to DVD") );
  287. actionToolsDvdCopy->setToolTip( i18n("Open the DVD copy dialog") );
  288. actionFileOpen->setToolTip(i18n("Opens an existing project"));
  289. actionFileOpenRecent->setToolTip(i18n("Opens a recently used file"));
  290. actionFileSave->setToolTip(i18n("Saves the current project"));
  291. actionFileSaveAs->setToolTip(i18n("Saves the current project to a new url"));
  292. actionFileSaveAll->setToolTip(i18n("Saves all open projects"));
  293. actionFileClose->setToolTip(i18n("Closes the current project"));
  294. actionFileCloseAll->setToolTip(i18n("Closes all open projects"));
  295. actionFileQuit->setToolTip(i18n("Quits the application"));
  296. actionSettingsConfigure->setToolTip( i18n("Configure K3b settings") );
  297. #ifdef HAVE_K3BSETUP
  298. actionSettingsK3bSetup->setToolTip( i18n("Setup the system permissions (requires root privileges)") );
  299. #endif
  300. actionToolsCddaRip->setToolTip( i18n("Digitally extract tracks from an audio CD") );
  301. actionToolsVideoDvdRip->setToolTip( i18n("Transcode Video DVD titles") );
  302. actionToolsVideoCdRip->setToolTip( i18n("Extract tracks from a Video CD") );
  303. actionProjectAddFiles->setToolTip( i18n("Add files to the current project") );
  304. actionClearProject->setToolTip( i18n("Clear the current project") );
  305. // make sure the tooltips are used for the menu
  306. actionCollection()->setHighlightingEnabled( true );
  307. }
  308. const TQPtrList<K3bDoc>& K3bMainWindow::projects() const
  309. {
  310. return k3bappcore->projectManager()->projects();
  311. }
  312. void K3bMainWindow::slotConfigureKeys()
  313. {
  314. KKeyDialog::configure( actionCollection(), this );
  315. }
  316. void K3bMainWindow::initStatusBar()
  317. {
  318. m_statusBarManager = new K3bStatusBarManager( this );
  319. }
  320. void K3bMainWindow::initView()
  321. {
  322. // setup main docking things
  323. mainDock = createDockWidget( "project_view", SmallIcon("idea"), 0,
  324. kapp->makeStdCaption( i18n("Project View") ), i18n("Project View") );
  325. mainDock->setDockSite( KDockWidget::DockCorner );
  326. mainDock->setEnableDocking( KDockWidget::DockNone );
  327. setView( mainDock );
  328. setMainDockWidget( mainDock );
  329. // --- Document Dock ----------------------------------------------------------------------------
  330. d->documentStack = new TQWidgetStack( mainDock );
  331. mainDock->setWidget( d->documentStack );
  332. d->documentHull = new TQWidget( d->documentStack );
  333. d->documentStack->addWidget( d->documentHull );
  334. TQGridLayout* documentHullLayout = new TQGridLayout( d->documentHull );
  335. documentHullLayout->setMargin( 2 );
  336. documentHullLayout->setSpacing( 0 );
  337. m_documentHeader = new K3bThemedHeader( d->documentHull );
  338. m_documentHeader->setTitle( i18n("Current Projects") );
  339. m_documentHeader->setAlignment( TQt::AlignHCenter | TQt::AlignVCenter );
  340. m_documentHeader->setLeftPixmap( K3bTheme::PROJECT_LEFT );
  341. m_documentHeader->setRightPixmap( K3bTheme::PROJECT_RIGHT );
  342. // add the document tab to the styled document box
  343. m_documentTab = new K3bProjectTabWidget( d->documentHull );
  344. documentHullLayout->addWidget( m_documentHeader, 0, 0 );
  345. documentHullLayout->addWidget( m_documentTab, 1, 0 );
  346. connect( m_documentTab, TQT_SIGNAL(currentChanged(TQWidget*)), TQT_TQOBJECT(this), TQT_SLOT(slotCurrentDocChanged()) );
  347. d->welcomeWidget = new K3bWelcomeWidget( this, m_documentTab );
  348. m_documentTab->addTab( d->welcomeWidget, i18n("Quickstart") );
  349. // d->documentStack->addWidget( d->welcomeWidget );
  350. // d->documentStack->raiseWidget( d->welcomeWidget );
  351. // ---------------------------------------------------------------------------------------------
  352. // --- Directory Dock --------------------------------------------------------------------------
  353. m_dirTreeDock = createDockWidget( "directory_tree", SmallIcon("folder"), 0,
  354. kapp->makeStdCaption( i18n("Sidepanel") ), i18n("Sidepanel") );
  355. m_dirTreeDock->setEnableDocking( KDockWidget::DockCorner );
  356. K3bFileTreeView* sidePanel = new K3bFileTreeView( m_dirTreeDock );
  357. //K3bSidePanel* sidePanel = new K3bSidePanel( this, m_dirTreeDock, "sidePanel" );
  358. m_dirTreeDock->setWidget( sidePanel );
  359. m_dirTreeDock->manualDock( mainDock, KDockWidget::DockTop, 4000 );
  360. connect( m_dirTreeDock, TQT_SIGNAL(iMBeingClosed()), TQT_TQOBJECT(this), TQT_SLOT(slotDirTreeDockHidden()) );
  361. connect( m_dirTreeDock, TQT_SIGNAL(hasUndocked()), TQT_TQOBJECT(this), TQT_SLOT(slotDirTreeDockHidden()) );
  362. // ---------------------------------------------------------------------------------------------
  363. // --- Contents Dock ---------------------------------------------------------------------------
  364. m_contentsDock = createDockWidget( "contents_view", SmallIcon("idea"), 0,
  365. kapp->makeStdCaption( i18n("Contents View") ), i18n("Contents View") );
  366. m_contentsDock->setEnableDocking( KDockWidget::DockCorner );
  367. m_dirView = new K3bDirView( sidePanel/*->fileTreeView()*/, m_contentsDock );
  368. m_contentsDock->setWidget( m_dirView );
  369. m_contentsDock->manualDock( m_dirTreeDock, KDockWidget::DockRight, 2000 );
  370. connect( m_contentsDock, TQT_SIGNAL(iMBeingClosed()), TQT_TQOBJECT(this), TQT_SLOT(slotContentsDockHidden()) );
  371. connect( m_contentsDock, TQT_SIGNAL(hasUndocked()), TQT_TQOBJECT(this), TQT_SLOT(slotContentsDockHidden()) );
  372. // ---------------------------------------------------------------------------------------------
  373. // --- filetreecombobox-toolbar ----------------------------------------------------------------
  374. K3bFileTreeComboBox* m_fileTreeComboBox = new K3bFileTreeComboBox( 0 );
  375. connect( m_fileTreeComboBox, TQT_SIGNAL(urlExecuted(const KURL&)), m_dirView, TQT_SLOT(showUrl(const KURL& )) );
  376. connect( m_fileTreeComboBox, TQT_SIGNAL(deviceExecuted(K3bDevice::Device*)), m_dirView,
  377. TQT_SLOT(showDevice(K3bDevice::Device* )) );
  378. connect( m_dirView, TQT_SIGNAL(urlEntered(const KURL&)), m_fileTreeComboBox, TQT_SLOT(setUrl(const KURL&)) );
  379. connect( m_dirView, TQT_SIGNAL(deviceSelected(K3bDevice::Device*)), m_fileTreeComboBox, TQT_SLOT(setDevice(K3bDevice::Device*)) );
  380. KWidgetAction* fileTreeComboAction = new KWidgetAction( m_fileTreeComboBox,
  381. i18n("&Quick Dir Selector"),
  382. 0, 0, 0,
  383. actionCollection(), "quick_dir_selector" );
  384. fileTreeComboAction->setAutoSized(true);
  385. (void)new TDEAction( i18n("Go"), "key_enter", 0, TQT_TQOBJECT(m_fileTreeComboBox), TQT_SLOT(slotGoUrl()), actionCollection(), "go_url" );
  386. // ---------------------------------------------------------------------------------------------
  387. }
  388. void K3bMainWindow::createClient( K3bDoc* doc )
  389. {
  390. // create the proper K3bView (maybe we should put this into some other class like K3bProjectManager)
  391. K3bView* view = 0;
  392. switch( doc->type() ) {
  393. case K3bDoc::AUDIO:
  394. view = new K3bAudioView( static_cast<K3bAudioDoc*>(doc), m_documentTab );
  395. break;
  396. case K3bDoc::DATA:
  397. view = new K3bDataView( static_cast<K3bDataDoc*>(doc), m_documentTab );
  398. break;
  399. case K3bDoc::MIXED:
  400. {
  401. K3bMixedDoc* mixedDoc = static_cast<K3bMixedDoc*>(doc);
  402. view = new K3bMixedView( mixedDoc, m_documentTab );
  403. mixedDoc->dataDoc()->setView( view );
  404. mixedDoc->audioDoc()->setView( view );
  405. break;
  406. }
  407. case K3bDoc::VCD:
  408. view = new K3bVcdView( static_cast<K3bVcdDoc*>(doc), m_documentTab );
  409. break;
  410. case K3bDoc::MOVIX:
  411. view = new K3bMovixView( static_cast<K3bMovixDoc*>(doc), m_documentTab );
  412. break;
  413. case K3bDoc::MOVIX_DVD:
  414. view = new K3bMovixDvdView( static_cast<K3bMovixDvdDoc*>(doc), m_documentTab );
  415. break;
  416. case K3bDoc::DVD:
  417. view = new K3bDvdView( static_cast<K3bDvdDoc*>(doc), m_documentTab );
  418. break;
  419. case K3bDoc::VIDEODVD:
  420. view = new K3bVideoDvdView( static_cast<K3bVideoDvdDoc*>(doc), m_documentTab );
  421. break;
  422. }
  423. doc->setView( view );
  424. view->setCaption( doc->URL().fileName() );
  425. m_documentTab->insertTab( doc );
  426. m_documentTab->showPage( view );
  427. slotCurrentDocChanged();
  428. }
  429. K3bView* K3bMainWindow::activeView() const
  430. {
  431. TQWidget* w = m_documentTab->currentPage();
  432. if( K3bView* view = dynamic_cast<K3bView*>(w) )
  433. return view;
  434. else
  435. return 0;
  436. }
  437. K3bDoc* K3bMainWindow::activeDoc() const
  438. {
  439. if( activeView() )
  440. return activeView()->getDocument();
  441. else
  442. return 0;
  443. }
  444. K3bDoc* K3bMainWindow::openDocument(const KURL& url)
  445. {
  446. slotStatusMsg(i18n("Opening file..."));
  447. //
  448. // First we check if this is an iso image in case someone wants to open one this way
  449. //
  450. if( !isCdDvdImageAndIfSoOpenDialog( url ) ) {
  451. // see if it's an audio cue file
  452. K3bCueFileParser parser( url.path() );
  453. if( parser.isValid() && parser.toc().contentType() == K3bDevice::AUDIO ) {
  454. K3bDoc* doc = k3bappcore->projectManager()->createProject( K3bDoc::AUDIO );
  455. doc->addUrl( url );
  456. return doc;
  457. }
  458. else {
  459. // check, if document already open. If yes, set the focus to the first view
  460. K3bDoc* doc = k3bappcore->projectManager()->findByUrl( url );
  461. if( doc ) {
  462. doc->view()->setFocus();
  463. return doc;
  464. }
  465. doc = k3bappcore->projectManager()->openProject( url );
  466. if( doc == 0 ) {
  467. KMessageBox::error (this,i18n("Could not open document!"), i18n("Error!"));
  468. return 0;
  469. }
  470. actionFileOpenRecent->addURL(url);
  471. return doc;
  472. }
  473. }
  474. else
  475. return 0;
  476. }
  477. void K3bMainWindow::saveOptions()
  478. {
  479. actionFileOpenRecent->saveEntries( config(), "Recent Files" );
  480. // save dock positions!
  481. manager()->writeConfig( config(), "Docking Config" );
  482. m_dirView->saveConfig( config() );
  483. saveMainWindowSettings( config(), "main_window_settings" );
  484. k3bcore->saveSettings( config() );
  485. d->welcomeWidget->saveConfig( config() );
  486. TDEConfigGroup grp( m_config, "General Options" );
  487. grp.writeEntry( "Show Document Header", actionViewDocumentHeader->isChecked() );
  488. }
  489. void K3bMainWindow::readOptions()
  490. {
  491. TDEConfigGroup grp( m_config, "General Options" );
  492. bool bViewDocumentHeader = grp.readBoolEntry("Show Document Header", true);
  493. actionViewDocumentHeader->setChecked(bViewDocumentHeader);
  494. // initialize the recent file list
  495. actionFileOpenRecent->loadEntries( config(), "Recent Files" );
  496. // do not read dock-positions from a config that has been saved by an old version
  497. K3bVersion configVersion( grp.readEntry( "config version", "0.1" ) );
  498. if( configVersion >= K3bVersion("0.12") )
  499. manager()->readConfig( config(), "Docking Config" );
  500. else
  501. kdDebug() << "(K3bMainWindow) ignoring docking config from K3b version " << configVersion << endl;
  502. applyMainWindowSettings( config(), "main_window_settings" );
  503. m_dirView->readConfig( config() );
  504. slotViewDocumentHeader();
  505. slotCheckDockWidgetStatus();
  506. }
  507. void K3bMainWindow::saveProperties( TDEConfig* c )
  508. {
  509. // 1. put saved projects in the config
  510. // 2. save every modified project in "~/.trinity/share/apps/k3b/sessions/" + KApp->sessionId()
  511. // 3. save the url of the project (might be something like "AudioCD1") in the config
  512. // 4. save the status of every project (modified/saved)
  513. TQString saveDir = TDEGlobal::dirs()->saveLocation( "appdata", "sessions/" + tqApp->sessionId() + "/", true );
  514. // FIXME: for some reason the config entries are not properly stored when using the default
  515. // TDEMainWindow session config. Since I was not able to find the bug I use another config object
  516. // ----------------------------------------------------------
  517. c = new KSimpleConfig( saveDir + "list", false );
  518. c->setGroup( "Saved Session" );
  519. // ----------------------------------------------------------
  520. const TQPtrList<K3bDoc>& docs = k3bappcore->projectManager()->projects();
  521. c->writeEntry( "Number of projects", docs.count() );
  522. int cnt = 1;
  523. for( TQPtrListIterator<K3bDoc> it( docs ); *it; ++it ) {
  524. // the "name" of the project (or the original url if isSaved())
  525. c->writePathEntry( TQString("%1 url").arg(cnt), (*it)->URL().url() );
  526. // is the doc modified
  527. c->writeEntry( TQString("%1 modified").arg(cnt), (*it)->isModified() );
  528. // has the doc already been saved?
  529. c->writeEntry( TQString("%1 saved").arg(cnt), (*it)->isSaved() );
  530. // where does the session management save it? If it's not modified and saved this is
  531. // the same as the url
  532. KURL saveUrl = (*it)->URL();
  533. if( !(*it)->isSaved() || (*it)->isModified() )
  534. saveUrl = KURL::fromPathOrURL( saveDir + TQString::number(cnt) );
  535. c->writePathEntry( TQString("%1 saveurl").arg(cnt), saveUrl.url() );
  536. // finally save it
  537. k3bappcore->projectManager()->saveProject( *it, saveUrl );
  538. ++cnt;
  539. }
  540. // FIXME: for some reason the config entries are not properly stored when using the default
  541. // TDEMainWindow session config. Since I was not able to find the bug I use another config object
  542. // ----------------------------------------------------------
  543. delete c;
  544. // ----------------------------------------------------------
  545. }
  546. // FIXME:move this to K3bProjectManager
  547. void K3bMainWindow::readProperties( TDEConfig* c )
  548. {
  549. // FIXME: do not delete the files here. rather do it when the app is exited normally
  550. // since that's when we can be sure we never need the session stuff again.
  551. // 1. read all projects from the config
  552. // 2. simply open all of themg
  553. // 3. reset the saved urls and the modified state
  554. // 4. delete "~/.trinity/share/apps/k3b/sessions/" + KApp->sessionId()
  555. TQString saveDir = TDEGlobal::dirs()->saveLocation( "appdata", "sessions/" + tqApp->sessionId() + "/", true );
  556. // FIXME: for some reason the config entries are not properly stored when using the default
  557. // TDEMainWindow session config. Since I was not able to find the bug I use another config object
  558. // ----------------------------------------------------------
  559. c = new KSimpleConfig( saveDir + "list", true );
  560. c->setGroup( "Saved Session" );
  561. // ----------------------------------------------------------
  562. int cnt = c->readNumEntry( "Number of projects", 0 );
  563. kdDebug() << "(K3bMainWindow::readProperties) number of projects from last session in " << saveDir << ": " << cnt << endl
  564. << " read from config group " << c->group() << endl;
  565. for( int i = 1; i <= cnt; ++i ) {
  566. // in this case the constructor works since we saved as url()
  567. KURL url = c->readPathEntry( TQString("%1 url").arg(i) );
  568. bool modified = c->readBoolEntry( TQString("%1 modified").arg(i) );
  569. bool saved = c->readBoolEntry( TQString("%1 saved").arg(i) );
  570. KURL saveUrl = c->readPathEntry( TQString("%1 saveurl").arg(i) );
  571. // now load the project
  572. if( K3bDoc* doc = k3bappcore->projectManager()->openProject( saveUrl ) ) {
  573. // reset the url
  574. doc->setURL( url );
  575. doc->setModified( modified );
  576. doc->setSaved( saved );
  577. }
  578. else
  579. kdDebug() << "(K3bMainWindow) could not open session saved doc " << url.path() << endl;
  580. // remove the temp file
  581. if( !saved || modified )
  582. TQFile::remove( saveUrl.path() );
  583. }
  584. // and now remove the temp dir
  585. TDEIO::del( KURL::fromPathOrURL(saveDir), false, false );
  586. // FIXME: for some reason the config entries are not properly stored when using the default
  587. // TDEMainWindow session config. Since I was not able to find the bug I use another config object
  588. // ----------------------------------------------------------
  589. delete c;
  590. // ----------------------------------------------------------
  591. }
  592. bool K3bMainWindow::queryClose()
  593. {
  594. //
  595. // Check if a job is currently running
  596. // For now K3b only allows for one major job at a time which means that we only need to cancel
  597. // this one job.
  598. //
  599. if( k3bcore->jobsRunning() ) {
  600. // pitty, but I see no possibility to make this work. It always crashes because of the event
  601. // management thing mentioned below. So until I find a solution K3b simply will refuse to close
  602. // while a job i running
  603. return false;
  604. // kdDebug() << "(K3bMainWindow::queryClose) jobs running." << endl;
  605. // K3bJob* job = k3bcore->runningJobs().getFirst();
  606. // // now search for the major job (to be on the safe side although for now no subjobs register with the k3bcore)
  607. // K3bJobHandler* jh = job->jobHandler();
  608. // while( jh->isJob() ) {
  609. // job = static_cast<K3bJob*>( jh );
  610. // jh = job->jobHandler();
  611. // }
  612. // kdDebug() << "(K3bMainWindow::queryClose) main job found: " << job->jobDescription() << endl;
  613. // // now job is the major job and jh should be a widget
  614. // TQWidget* progressDialog = dynamic_cast<TQWidget*>( jh );
  615. // kdDebug() << "(K3bMainWindow::queryClose) job active: " << job->active() << endl;
  616. // // now ask the user if he/she really wants to cancel this job
  617. // if( job->active() ) {
  618. // if( KMessageBox::questionYesNo( progressDialog ? progressDialog : this,
  619. // i18n("Do you really want to cancel?"),
  620. // i18n("Cancel") ) == KMessageBox::Yes ) {
  621. // // cancel the job
  622. // kdDebug() << "(K3bMainWindow::queryClose) canceling job." << endl;
  623. // job->cancel();
  624. // // wait for the job to finish
  625. // kdDebug() << "(K3bMainWindow::queryClose) waiting for job to finish." << endl;
  626. // K3bSignalWaiter::waitForJob( job );
  627. // // close the progress dialog
  628. // if( progressDialog ) {
  629. // kdDebug() << "(K3bMainWindow::queryClose) closing progress dialog." << endl;
  630. // progressDialog->close();
  631. // //
  632. // // now here we have the problem that due to the whole TQt event thing the exec call (or
  633. // // in this case most likely the startJob call) does not return until we leave this method.
  634. // // That means that the progress dialog might be deleted by it's parent below (when we
  635. // // close docs) before it is deleted by the creator (most likely a projectburndialog).
  636. // // That would result in a double deletion and thus a crash.
  637. // // So we just reparent the dialog to 0 here so it's (former) parent won't delete it.
  638. // //
  639. // progressDialog->reparent( 0, TQPoint(0,0) );
  640. // }
  641. // kdDebug() << "(K3bMainWindow::queryClose) job cleanup done." << endl;
  642. // }
  643. // else
  644. // return false;
  645. // }
  646. }
  647. //
  648. // if we are closed by the session manager everything is fine since we store the
  649. // current state in saveProperties
  650. //
  651. if( kapp->sessionSaving() )
  652. return true;
  653. // FIXME: do not close the docs here. Just ask for them to be saved and return false
  654. // if the user chose cancel for some doc
  655. // ---------------------------------
  656. // we need to manually close all the views to ensure that
  657. // each of them receives a close-event and
  658. // the user is asked for every modified doc to save the changes
  659. // ---------------------------------
  660. while( K3bView* view = activeView() ) {
  661. if( !canCloseDocument(view->doc()) )
  662. return false;
  663. closeProject(view->doc());
  664. }
  665. return true;
  666. }
  667. bool K3bMainWindow::canCloseDocument( K3bDoc* doc )
  668. {
  669. if( !doc->isModified() )
  670. return true;
  671. if( !TDEConfigGroup( config(), "General Options" ).readBoolEntry( "ask_for_saving_changes_on_exit", true ) )
  672. return true;
  673. switch ( KMessageBox::warningYesNoCancel( this,
  674. i18n("%1 has unsaved data.").arg( doc->URL().fileName() ),
  675. i18n("Closing Project"),
  676. KStdGuiItem::save(),
  677. KGuiItem( i18n("&Discard"), "editshred" ) ) )
  678. {
  679. case KMessageBox::Yes:
  680. fileSave( doc );
  681. case KMessageBox::No:
  682. return true;
  683. default:
  684. return false;
  685. }
  686. }
  687. bool K3bMainWindow::queryExit()
  688. {
  689. // TODO: call this in K3bApplication somewhere
  690. saveOptions();
  691. return true;
  692. }
  693. /////////////////////////////////////////////////////////////////////
  694. // TQT_SLOT IMPLEMENTATION
  695. /////////////////////////////////////////////////////////////////////
  696. void K3bMainWindow::slotFileOpen()
  697. {
  698. slotStatusMsg(i18n("Opening file..."));
  699. KURL::List urls = KFileDialog::getOpenURLs( ":k3b-projects-folder",
  700. i18n("*.k3b|K3b Projects"),
  701. this,
  702. i18n("Open Files") );
  703. for( KURL::List::iterator it = urls.begin(); it != urls.end(); ++it ) {
  704. openDocument( *it );
  705. actionFileOpenRecent->addURL( *it );
  706. }
  707. }
  708. void K3bMainWindow::slotFileOpenRecent(const KURL& url)
  709. {
  710. slotStatusMsg(i18n("Opening file..."));
  711. openDocument(url);
  712. }
  713. void K3bMainWindow::slotFileSaveAll()
  714. {
  715. for( TQPtrListIterator<K3bDoc> it( k3bappcore->projectManager()->projects() );
  716. *it; ++it ) {
  717. fileSave( *it );
  718. }
  719. }
  720. void K3bMainWindow::slotFileSave()
  721. {
  722. if( K3bDoc* doc = activeDoc() ) {
  723. fileSave( doc );
  724. }
  725. }
  726. void K3bMainWindow::fileSave( K3bDoc* doc )
  727. {
  728. slotStatusMsg(i18n("Saving file..."));
  729. if( doc == 0 ) {
  730. doc = activeDoc();
  731. }
  732. if( doc != 0 ) {
  733. if( !doc->isSaved() )
  734. fileSaveAs( doc );
  735. else if( !k3bappcore->projectManager()->saveProject( doc, doc->URL()) )
  736. KMessageBox::error (this,i18n("Could not save the current document!"), i18n("I/O Error"));
  737. }
  738. }
  739. void K3bMainWindow::slotFileSaveAs()
  740. {
  741. if( K3bDoc* doc = activeDoc() ) {
  742. fileSaveAs( doc );
  743. }
  744. }
  745. void K3bMainWindow::fileSaveAs( K3bDoc* doc )
  746. {
  747. slotStatusMsg(i18n("Saving file with a new filename..."));
  748. if( doc == 0 ) {
  749. doc = activeDoc();
  750. }
  751. if( doc != 0 ) {
  752. // we do not use the static KFileDialog method here to be able to specify a filename suggestion
  753. KFileDialog dlg( ":k3b-projects-folder", i18n("*.k3b|K3b Projects"), this, "filedialog", true );
  754. dlg.setCaption( i18n("Save As") );
  755. dlg.setOperationMode( KFileDialog::Saving );
  756. dlg.setSelection( doc->name() );
  757. dlg.exec();
  758. KURL url = dlg.selectedURL();
  759. if( url.isValid() ) {
  760. TDERecentDocument::add( url );
  761. bool exists = TDEIO::NetAccess::exists( url, false, 0 );
  762. if( !exists ||
  763. ( exists &&
  764. KMessageBox::warningContinueCancel( this, i18n("Do you want to overwrite %1?").arg( url.prettyURL() ),
  765. i18n("File Exists"), i18n("Overwrite") )
  766. == KMessageBox::Continue ) ) {
  767. if( !k3bappcore->projectManager()->saveProject( doc, url ) ) {
  768. KMessageBox::error (this,i18n("Could not save the current document!"), i18n("I/O Error"));
  769. return;
  770. }
  771. else
  772. actionFileOpenRecent->addURL(url);
  773. }
  774. }
  775. }
  776. }
  777. void K3bMainWindow::slotFileClose()
  778. {
  779. slotStatusMsg(i18n("Closing file..."));
  780. if( K3bView* pView = activeView() ) {
  781. if( pView ) {
  782. K3bDoc* pDoc = pView->doc();
  783. if( canCloseDocument(pDoc) ) {
  784. closeProject(pDoc);
  785. }
  786. }
  787. }
  788. slotCurrentDocChanged();
  789. }
  790. void K3bMainWindow::slotFileCloseAll()
  791. {
  792. while( K3bView* pView = activeView() ) {
  793. if( pView ) {
  794. K3bDoc* pDoc = pView->doc();
  795. if( canCloseDocument(pDoc) )
  796. closeProject(pDoc);
  797. else
  798. break;
  799. }
  800. }
  801. slotCurrentDocChanged();
  802. }
  803. void K3bMainWindow::closeProject( K3bDoc* doc )
  804. {
  805. // unplug the actions
  806. if( factory() ) {
  807. if( d->lastDoc == doc ) {
  808. factory()->removeClient( static_cast<K3bView*>(d->lastDoc->view()) );
  809. d->lastDoc = 0;
  810. }
  811. }
  812. // remove the view from the project tab
  813. m_documentTab->removePage( doc->view() );
  814. // remove the project from the manager
  815. k3bappcore->projectManager()->removeProject( doc );
  816. // delete view and doc
  817. delete doc->view();
  818. delete doc;
  819. }
  820. void K3bMainWindow::slotFileQuit()
  821. {
  822. close();
  823. }
  824. void K3bMainWindow::slotViewStatusBar()
  825. {
  826. //turn Statusbar on or off
  827. if(actionViewStatusBar->isChecked()) {
  828. statusBar()->show();
  829. }
  830. else {
  831. statusBar()->hide();
  832. }
  833. }
  834. void K3bMainWindow::slotStatusMsg(const TQString &text)
  835. {
  836. ///////////////////////////////////////////////////////////////////
  837. // change status message permanently
  838. // statusBar()->clear();
  839. // statusBar()->changeItem(text,1);
  840. statusBar()->message( text, 2000 );
  841. }
  842. void K3bMainWindow::slotSettingsConfigure()
  843. {
  844. K3bOptionDialog d( this, "SettingsDialog", true );
  845. d.exec();
  846. // emit a changed signal every time since we do not know if the user selected
  847. // "apply" and "cancel" or "ok"
  848. emit configChanged( m_config );
  849. }
  850. void K3bMainWindow::showOptionDialog( int index )
  851. {
  852. K3bOptionDialog d( this, "SettingsDialog", true );
  853. d.showPage( index );
  854. d.exec();
  855. // emit a changed signal every time since we do not know if the user selected
  856. // "apply" and "cancel" or "ok"
  857. emit configChanged( m_config );
  858. }
  859. K3bDoc* K3bMainWindow::slotNewAudioDoc()
  860. {
  861. slotStatusMsg(i18n("Creating new Audio CD Project."));
  862. K3bDoc* doc = k3bappcore->projectManager()->createProject( K3bDoc::AUDIO );
  863. return doc;
  864. }
  865. K3bDoc* K3bMainWindow::slotNewDataDoc()
  866. {
  867. slotStatusMsg(i18n("Creating new Data CD Project."));
  868. K3bDoc* doc = k3bappcore->projectManager()->createProject( K3bDoc::DATA );
  869. return doc;
  870. }
  871. K3bDoc* K3bMainWindow::slotNewDvdDoc()
  872. {
  873. slotStatusMsg(i18n("Creating new Data DVD Project."));
  874. K3bDoc* doc = k3bappcore->projectManager()->createProject( K3bDoc::DVD );
  875. return doc;
  876. }
  877. K3bDoc* K3bMainWindow::slotContinueMultisession()
  878. {
  879. return K3bDataSessionImportDialog::importSession( 0, this );
  880. }
  881. K3bDoc* K3bMainWindow::slotNewVideoDvdDoc()
  882. {
  883. slotStatusMsg(i18n("Creating new VideoDVD Project."));
  884. K3bDoc* doc = k3bappcore->projectManager()->createProject( K3bDoc::VIDEODVD );
  885. return doc;
  886. }
  887. K3bDoc* K3bMainWindow::slotNewMixedDoc()
  888. {
  889. slotStatusMsg(i18n("Creating new Mixed Mode CD Project."));
  890. K3bDoc* doc = k3bappcore->projectManager()->createProject( K3bDoc::MIXED );
  891. return doc;
  892. }
  893. K3bDoc* K3bMainWindow::slotNewVcdDoc()
  894. {
  895. slotStatusMsg(i18n("Creating new Video CD Project."));
  896. K3bDoc* doc = k3bappcore->projectManager()->createProject( K3bDoc::VCD );
  897. return doc;
  898. }
  899. K3bDoc* K3bMainWindow::slotNewMovixDoc()
  900. {
  901. slotStatusMsg(i18n("Creating new eMovix CD Project."));
  902. K3bDoc* doc = k3bappcore->projectManager()->createProject( K3bDoc::MOVIX );
  903. return doc;
  904. }
  905. K3bDoc* K3bMainWindow::slotNewMovixDvdDoc()
  906. {
  907. slotStatusMsg(i18n("Creating new eMovix DVD Project."));
  908. K3bDoc* doc = k3bappcore->projectManager()->createProject( K3bDoc::MOVIX_DVD );
  909. return doc;
  910. }
  911. void K3bMainWindow::slotCurrentDocChanged()
  912. {
  913. // check the doctype
  914. K3bView* v = activeView();
  915. if( v ) {
  916. k3bappcore->projectManager()->setActive( v->doc() );
  917. //
  918. // There are two possiblities to plug the project actions:
  919. // 1. Through KXMLGUIClient::plugActionList
  920. // This way we just ask the View for the actionCollection (which it should merge with
  921. // the doc's) and plug it into the project menu.
  922. // Advantage: easy and clear to handle
  923. // Disadvantage: we may only plug all actions at once into one menu
  924. //
  925. // 2. Through merging the doc as a KXMLGUIClient
  926. // This way every view is a KXMLGUIClient and it's GUI is just merged into the MainWindow's.
  927. // Advantage: flexible
  928. // Disadvantage: every view needs it's own XML file
  929. //
  930. //
  931. if( factory() ) {
  932. if( d->lastDoc )
  933. factory()->removeClient( static_cast<K3bView*>(d->lastDoc->view()) );
  934. factory()->addClient( v );
  935. d->lastDoc = v->doc();
  936. }
  937. else
  938. kdDebug() << "(K3bMainWindow) ERROR: could not get KXMLGUIFactory instance." << endl;
  939. }
  940. else
  941. k3bappcore->projectManager()->setActive( 0L );
  942. if( k3bappcore->projectManager()->isEmpty() ) {
  943. slotStateChanged( "state_project_active", KXMLGUIClient::StateReverse );
  944. }
  945. else {
  946. d->documentStack->raiseWidget( d->documentHull );
  947. slotStateChanged( "state_project_active", KXMLGUIClient::StateNoReverse );
  948. }
  949. // make sure the document header is shown (or not)
  950. slotViewDocumentHeader();
  951. }
  952. void K3bMainWindow::slotEditToolbars()
  953. {
  954. saveMainWindowSettings( m_config, "main_window_settings" );
  955. KEditToolbar dlg( factory() );
  956. connect(&dlg, TQT_SIGNAL(newToolbarConfig()), TQT_SLOT(slotNewToolBarConfig()));
  957. dlg.exec();
  958. }
  959. void K3bMainWindow::slotNewToolBarConfig()
  960. {
  961. applyMainWindowSettings( m_config, "main_window_settings" );
  962. }
  963. bool K3bMainWindow::eject()
  964. {
  965. TDEConfigGroup c( config(), "General Options" );
  966. return !c.readBoolEntry( "No cd eject", false );
  967. }
  968. void K3bMainWindow::slotErrorMessage(const TQString& message)
  969. {
  970. KMessageBox::error( this, message );
  971. }
  972. void K3bMainWindow::slotWarningMessage(const TQString& message)
  973. {
  974. KMessageBox::sorry( this, message );
  975. }
  976. void K3bMainWindow::slotWriteCdImage()
  977. {
  978. K3bCdImageWritingDialog d( this );
  979. d.exec(false);
  980. }
  981. void K3bMainWindow::slotWriteDvdIsoImage()
  982. {
  983. K3bIsoImageWritingDialog d( this );
  984. d.exec(false);
  985. }
  986. void K3bMainWindow::slotWriteDvdIsoImage( const KURL& url )
  987. {
  988. K3bIsoImageWritingDialog d( this );
  989. d.setImage( url );
  990. d.exec(false);
  991. }
  992. void K3bMainWindow::slotWriteCdImage( const KURL& url )
  993. {
  994. K3bCdImageWritingDialog d( this );
  995. d.setImage( url );
  996. d.exec(false);
  997. }
  998. void K3bMainWindow::slotProjectAddFiles()
  999. {
  1000. K3bView* view = activeView();
  1001. if( view ) {
  1002. TQStringList files = KFileDialog::getOpenFileNames( ":k3b-project-add-files",
  1003. i18n("*|All Files"),
  1004. this,
  1005. i18n("Select Files to Add to Project") );
  1006. KURL::List urls;
  1007. for( TQStringList::ConstIterator it = files.begin();
  1008. it != files.end(); it++ ) {
  1009. KURL url;
  1010. url.setPath(*it);
  1011. urls.append( url );
  1012. }
  1013. if( !urls.isEmpty() )
  1014. view->addUrls( urls );
  1015. }
  1016. else
  1017. KMessageBox::error( this, i18n("Please create a project before adding files"), i18n("No Active Project"));
  1018. }
  1019. void K3bMainWindow::slotK3bSetup()
  1020. {
  1021. TDEProcess p;
  1022. p << "tdesu" << "tdecmshell k3bsetup2 --lang " + TDEGlobal::locale()->language();
  1023. if( !p.start( TDEProcess::DontCare ) )
  1024. KMessageBox::error( 0, i18n("Could not find tdesu to run K3bSetup with root privileges. "
  1025. "Please run it manually as root.") );
  1026. }
  1027. void K3bMainWindow::blankCdrw( K3bDevice::Device* dev )
  1028. {
  1029. K3bBlankingDialog dlg( this, "blankingdialog" );
  1030. dlg.setDevice( dev );
  1031. dlg.exec(false);
  1032. }
  1033. void K3bMainWindow::slotBlankCdrw()
  1034. {
  1035. blankCdrw( 0 );
  1036. }
  1037. void K3bMainWindow::formatDvd( K3bDevice::Device* dev )
  1038. {
  1039. K3bDvdFormattingDialog d( this );
  1040. d.setDevice( dev );
  1041. d.exec(false);
  1042. }
  1043. void K3bMainWindow::slotFormatDvd()
  1044. {
  1045. formatDvd( 0 );
  1046. }
  1047. void K3bMainWindow::cdCopy( K3bDevice::Device* dev )
  1048. {
  1049. K3bCdCopyDialog d( this );
  1050. d.setReadingDevice( dev );
  1051. d.exec(false);
  1052. }
  1053. void K3bMainWindow::slotCdCopy()
  1054. {
  1055. cdCopy( 0 );
  1056. }
  1057. void K3bMainWindow::dvdCopy( K3bDevice::Device* dev )
  1058. {
  1059. K3bDvdCopyDialog d( this );
  1060. d.setReadingDevice( dev );
  1061. d.exec(false);
  1062. }
  1063. void K3bMainWindow::slotDvdCopy()
  1064. {
  1065. dvdCopy( 0 );
  1066. }
  1067. // void K3bMainWindow::slotVideoDvdCopy()
  1068. // {
  1069. // K3bVideoDvdCopyDialog d( this );
  1070. // d.exec();
  1071. // }
  1072. void K3bMainWindow::slotShowDirTreeView()
  1073. {
  1074. m_dirTreeDock->changeHideShowState();
  1075. slotCheckDockWidgetStatus();
  1076. }
  1077. void K3bMainWindow::slotShowContentsView()
  1078. {
  1079. m_contentsDock->changeHideShowState();
  1080. slotCheckDockWidgetStatus();
  1081. }
  1082. void K3bMainWindow::slotShowMenuBar()
  1083. {
  1084. if( menuBar()->isVisible() )
  1085. menuBar()->hide();
  1086. else
  1087. menuBar()->show();
  1088. }
  1089. void K3bMainWindow::slotShowTips()
  1090. {
  1091. KTipDialog::showTip( this, TQString(), true );
  1092. }
  1093. void K3bMainWindow::slotDirTreeDockHidden()
  1094. {
  1095. actionViewDirTreeView->setChecked( false );
  1096. }
  1097. void K3bMainWindow::slotContentsDockHidden()
  1098. {
  1099. actionViewContentsView->setChecked( false );
  1100. }
  1101. void K3bMainWindow::slotCheckDockWidgetStatus()
  1102. {
  1103. actionViewContentsView->setChecked( m_contentsDock->isVisible() );
  1104. actionViewDirTreeView->setChecked( m_dirTreeDock->isVisible() );
  1105. }
  1106. void K3bMainWindow::slotViewDocumentHeader()
  1107. {
  1108. if( actionViewDocumentHeader->isChecked() &&
  1109. !k3bappcore->projectManager()->isEmpty() ) {
  1110. m_documentHeader->show();
  1111. }
  1112. else {
  1113. m_documentHeader->hide();
  1114. }
  1115. }
  1116. K3bExternalBinManager* K3bMainWindow::externalBinManager() const
  1117. {
  1118. return k3bcore->externalBinManager();
  1119. }
  1120. K3bDevice::DeviceManager* K3bMainWindow::deviceManager() const
  1121. {
  1122. return k3bcore->deviceManager();
  1123. }
  1124. void K3bMainWindow::slotDataImportSession()
  1125. {
  1126. if( activeView() ) {
  1127. if( K3bDataView* view = dynamic_cast<K3bDataView*>(activeView()) ) {
  1128. view->importSession();
  1129. }
  1130. }
  1131. }
  1132. void K3bMainWindow::slotDataClearImportedSession()
  1133. {
  1134. if( activeView() ) {
  1135. if( K3bDataView* view = dynamic_cast<K3bDataView*>(activeView()) ) {
  1136. view->clearImportedSession();
  1137. }
  1138. }
  1139. }
  1140. void K3bMainWindow::slotEditBootImages()
  1141. {
  1142. if( activeView() ) {
  1143. if( K3bDataView* view = dynamic_cast<K3bDataView*>(activeView()) ) {
  1144. view->editBootImages();
  1145. }
  1146. }
  1147. }
  1148. void K3bMainWindow::slotCheckSystemTimed()
  1149. {
  1150. // run the system check from the event queue so we do not
  1151. // mess with the device state resetting throughout the app
  1152. // when called from K3bDeviceManager::changed
  1153. TQTimer::singleShot( 0, TQT_TQOBJECT(this), TQT_SLOT(slotCheckSystem()) );
  1154. }
  1155. void K3bMainWindow::slotCheckSystem()
  1156. {
  1157. K3bSystemProblemDialog::checkSystem( this );
  1158. }
  1159. void K3bMainWindow::addUrls( const KURL::List& urls )
  1160. {
  1161. if( K3bView* view = activeView() ) {
  1162. view->addUrls( urls );
  1163. }
  1164. else {
  1165. // check if the files are all audio we can handle. If so create an audio project
  1166. bool audio = true;
  1167. TQPtrList<K3bPlugin> fl = k3bcore->pluginManager()->plugins( "AudioDecoder" );
  1168. for( KURL::List::const_iterator it = urls.begin(); it != urls.end(); ++it ) {
  1169. const KURL& url = *it;
  1170. if( TQFileInfo(url.path()).isDir() ) {
  1171. audio = false;
  1172. break;
  1173. }
  1174. bool a = false;
  1175. for( TQPtrListIterator<K3bPlugin> it( fl ); it.current(); ++it ) {
  1176. if( static_cast<K3bAudioDecoderFactory*>(it.current())->canDecode( url ) ) {
  1177. a = true;
  1178. break;
  1179. }
  1180. }
  1181. if( !a ) {
  1182. audio = a;
  1183. break;
  1184. }
  1185. }
  1186. if( !audio && urls.count() == 1 ) {
  1187. // see if it's an audio cue file
  1188. K3bCueFileParser parser( urls.first().path() );
  1189. if( parser.isValid() && parser.toc().contentType() == K3bDevice::AUDIO ) {
  1190. audio = true;
  1191. }
  1192. }
  1193. if( audio )
  1194. static_cast<K3bView*>(slotNewAudioDoc()->view())->addUrls( urls );
  1195. else if( urls.count() > 1 || !isCdDvdImageAndIfSoOpenDialog( urls.first() ) )
  1196. static_cast<K3bView*>(slotNewDataDoc()->view())->addUrls( urls );
  1197. }
  1198. }
  1199. void K3bMainWindow::slotClearProject()
  1200. {
  1201. K3bDoc* doc = k3bappcore->projectManager()->activeDoc();
  1202. if( doc ) {
  1203. if( KMessageBox::warningContinueCancel( this,
  1204. i18n("Do you really want to clear the current project?"),
  1205. i18n("Clear Project"),
  1206. i18n("Clear"),
  1207. "clear_current_project_dontAskAgain" ) == KMessageBox::Continue ) {
  1208. doc->newDocument();
  1209. k3bappcore->projectManager()->loadDefaults( doc );
  1210. }
  1211. }
  1212. }
  1213. bool K3bMainWindow::isCdDvdImageAndIfSoOpenDialog( const KURL& url )
  1214. {
  1215. K3bIso9660 iso( url.path() );
  1216. if( iso.open() ) {
  1217. iso.close();
  1218. // very rough dvd image size test
  1219. if( K3b::filesize( url ) > 1000*1024*1024 )
  1220. slotWriteDvdIsoImage( url );
  1221. else
  1222. slotWriteCdImage( url );
  1223. return true;
  1224. }
  1225. else
  1226. return false;
  1227. }
  1228. void K3bMainWindow::slotCddaRip()
  1229. {
  1230. cddaRip( 0 );
  1231. }
  1232. void K3bMainWindow::cddaRip( K3bDevice::Device* dev )
  1233. {
  1234. if( !dev ||
  1235. !(k3bappcore->mediaCache()->medium( dev ).content() & K3bMedium::CONTENT_AUDIO ) )
  1236. dev = K3bMediaSelectionDialog::selectMedium( K3bDevice::MEDIA_CD_ALL,
  1237. K3bDevice::STATE_COMPLETE|K3bDevice::STATE_INCOMPLETE,
  1238. K3bMedium::CONTENT_AUDIO,
  1239. this,
  1240. i18n("Audio CD Rip") );
  1241. if( dev )
  1242. m_dirView->showDevice( dev );
  1243. }
  1244. void K3bMainWindow::videoDvdRip( K3bDevice::Device* dev )
  1245. {
  1246. if( !dev ||
  1247. !(k3bappcore->mediaCache()->medium( dev ).content() & K3bMedium::CONTENT_VIDEO_DVD ) )
  1248. dev = K3bMediaSelectionDialog::selectMedium( K3bDevice::MEDIA_DVD_ALL,
  1249. K3bDevice::STATE_COMPLETE,
  1250. K3bMedium::CONTENT_VIDEO_DVD,
  1251. this,
  1252. i18n("Video DVD Rip") );
  1253. if( dev )
  1254. m_dirView->showDevice( dev );
  1255. }
  1256. void K3bMainWindow::slotVideoDvdRip()
  1257. {
  1258. videoDvdRip( 0 );
  1259. }
  1260. void K3bMainWindow::videoCdRip( K3bDevice::Device* dev )
  1261. {
  1262. if( !dev ||
  1263. !(k3bappcore->mediaCache()->medium( dev ).content() & K3bMedium::CONTENT_VIDEO_CD ) )
  1264. dev = K3bMediaSelectionDialog::selectMedium( K3bDevice::MEDIA_CD_ALL,
  1265. K3bDevice::STATE_COMPLETE,
  1266. K3bMedium::CONTENT_VIDEO_CD,
  1267. this,
  1268. i18n("Video CD Rip") );
  1269. if( dev )
  1270. m_dirView->showDevice( dev );
  1271. }
  1272. void K3bMainWindow::slotVideoCdRip()
  1273. {
  1274. videoCdRip( 0 );
  1275. }
  1276. void K3bMainWindow::slotAudioServerError( const TQString& error )
  1277. {
  1278. K3bPassivePopup::showPopup( error, i18n("Audio Output Problem") );
  1279. }
  1280. #include "k3b.moc"