2013-09-23 14:41:52 -04:00
/*
2019-08-02 17:26:43 -04:00
* Copyright ( C ) 2013 - 2019 Paul Davis < paul @ linuxaudiosystems . com >
* Copyright ( C ) 2014 - 2015 Tim Mayberry < mojofunk @ gmail . com >
* Copyright ( C ) 2014 - 2019 Robin Gareus < robin @ gareus . org >
* Copyright ( C ) 2014 Colin Fletcher < colin . m . fletcher @ googlemail . com >
* Copyright ( C ) 2015 Nick Mainsbridge < mainsbridge @ gmail . com >
* Copyright ( C ) 2017 Ben Loftis < ben @ harrisonconsoles . com >
*
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation ; either version 2 of the License , or
* ( at your option ) any later version .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License along
* with this program ; if not , write to the Free Software Foundation , Inc . ,
* 51 Franklin Street , Fifth Floor , Boston , MA 02110 - 1301 USA .
*/
2013-09-23 14:41:52 -04:00
# ifdef WAF_BUILD
# include "gtk2ardour-config.h"
# endif
# include <algorithm>
2015-09-15 19:20:27 -04:00
# include <glib.h>
2015-10-05 16:10:58 -04:00
# include "pbd/gstdio_compat.h"
2015-09-16 15:32:59 -04:00
# include <glibmm.h>
2015-09-15 19:20:27 -04:00
2013-09-23 14:41:52 -04:00
# include <gtkmm/filechooser.h>
2017-07-16 22:55:52 -04:00
# include <gtkmm/stock.h>
2013-09-23 14:41:52 -04:00
2015-11-19 21:21:57 -05:00
# include "pbd/basename.h"
2013-09-23 14:41:52 -04:00
# include "pbd/failed_constructor.h"
# include "pbd/file_utils.h"
# include "pbd/replace_all.h"
# include "pbd/whitespace.h"
2014-06-14 22:09:48 -04:00
# include "pbd/stl_delete.h"
2013-09-23 14:41:52 -04:00
# include "pbd/openuri.h"
2015-10-15 05:24:15 -04:00
# include "gtkmm2ext/utils.h"
2016-10-06 11:42:46 -04:00
# include "gtkmm2ext/keyboard.h"
2015-10-15 05:24:15 -04:00
2017-07-15 11:38:28 -04:00
# include "widgets/tooltips.h"
2013-09-23 14:41:52 -04:00
# include "ardour/audioengine.h"
# include "ardour/filesystem_paths.h"
2017-08-11 08:29:08 -04:00
# include "ardour/luascripting.h"
2013-09-23 14:41:52 -04:00
# include "ardour/recent_sessions.h"
# include "ardour/session.h"
# include "ardour/session_state_utils.h"
# include "ardour/template_utils.h"
# include "ardour/filename_extensions.h"
2017-08-15 23:02:26 -04:00
# include "LuaBridge/LuaBridge.h"
2020-06-09 14:30:10 -04:00
# include "ardour_message.h"
2013-09-23 14:41:52 -04:00
# include "ardour_ui.h"
# include "session_dialog.h"
# include "opts.h"
# include "engine_dialog.h"
2016-07-14 14:44:52 -04:00
# include "pbd/i18n.h"
2015-09-16 17:11:54 -04:00
# include "ui_config.h"
2013-09-23 14:41:52 -04:00
# include "utils.h"
using namespace std ;
using namespace Gtk ;
using namespace Gdk ;
using namespace Glib ;
using namespace PBD ;
using namespace ARDOUR ;
2017-07-15 11:38:28 -04:00
using namespace ArdourWidgets ;
2014-06-25 15:27:37 -04:00
using namespace ARDOUR_UI_UTILS ;
2013-09-23 14:41:52 -04:00
2013-09-23 23:13:07 -04:00
SessionDialog : : SessionDialog ( bool require_new , const std : : string & session_name , const std : : string & session_path , const std : : string & template_name , bool cancel_not_quit )
: ArdourDialog ( _ ( " Session Setup " ) , true , true )
2013-09-23 14:41:52 -04:00
, new_only ( require_new )
2020-03-24 02:00:33 -04:00
, new_name_was_edited ( false )
2013-09-23 14:41:52 -04:00
, new_folder_chooser ( FILE_CHOOSER_ACTION_SELECT_FOLDER )
, _existing_session_chooser_used ( false )
{
set_position ( WIN_POS_CENTER ) ;
2013-09-23 16:49:24 -04:00
get_vbox ( ) - > set_spacing ( 6 ) ;
2013-09-23 14:41:52 -04:00
2013-09-24 22:22:16 -04:00
cancel_button = add_button ( ( cancel_not_quit ? Stock : : CANCEL : Stock : : QUIT ) , RESPONSE_CANCEL ) ;
back_button = add_button ( Stock : : GO_BACK , RESPONSE_NO ) ;
open_button = add_button ( Stock : : OPEN , RESPONSE_ACCEPT ) ;
back_button - > signal_button_press_event ( ) . connect ( sigc : : mem_fun ( * this , & SessionDialog : : back_button_pressed ) , false ) ;
2016-10-06 11:42:46 -04:00
open_button - > signal_button_press_event ( ) . connect ( sigc : : mem_fun ( * this , & SessionDialog : : open_button_pressed ) , false ) ;
2013-09-24 22:22:16 -04:00
open_button - > set_sensitive ( false ) ;
2019-07-18 15:35:27 -04:00
back_button - > set_sensitive ( false ) ;
2013-09-24 22:22:16 -04:00
2013-09-23 16:49:24 -04:00
/* this is where announcements will be displayed, but it may be empty
* and invisible most of the time .
*/
2017-09-18 14:45:56 -04:00
info_frame . set_shadow_type ( SHADOW_ETCHED_OUT ) ;
info_frame . set_no_show_all ( true ) ;
info_frame . set_border_width ( 12 ) ;
get_vbox ( ) - > pack_start ( info_frame , false , false ) ;
2013-09-23 16:49:24 -04:00
2019-07-18 10:16:11 -04:00
if ( ! template_name . empty ( ) ) {
load_template_override = template_name ;
}
2013-09-23 14:41:52 -04:00
setup_new_session_page ( ) ;
2015-10-05 10:17:49 -04:00
2019-07-18 12:44:10 -04:00
if ( ! require_new ) {
2013-09-23 14:41:52 -04:00
setup_initial_choice_box ( ) ;
get_vbox ( ) - > pack_start ( ic_vbox , true , true ) ;
} else {
get_vbox ( ) - > pack_start ( session_new_vbox , true , true ) ;
}
2015-10-05 10:17:49 -04:00
2013-09-23 14:41:52 -04:00
get_vbox ( ) - > show_all ( ) ;
2014-09-22 08:21:14 -04:00
/* fill data models and show/hide accordingly */
2013-09-23 14:41:52 -04:00
populate_session_templates ( ) ;
if ( recent_session_model ) {
int cnt = redisplay_recent_sessions ( ) ;
if ( cnt > 0 ) {
recent_scroller . show ( ) ;
recent_label . show ( ) ;
2015-10-05 10:17:49 -04:00
2013-09-23 14:41:52 -04:00
if ( cnt > 4 ) {
recent_scroller . set_size_request ( - 1 , 300 ) ;
2015-10-24 13:12:38 -04:00
} else {
recent_scroller . set_size_request ( - 1 , 80 ) ;
2013-09-23 14:41:52 -04:00
}
} else {
recent_scroller . hide ( ) ;
recent_label . hide ( ) ;
}
}
2020-02-06 15:38:02 -05:00
inital_height = get_height ( ) ;
inital_width = get_width ( ) ;
2020-03-24 21:43:20 -04:00
if ( require_new ) {
setup_untitled_session ( ) ;
}
2022-12-12 12:17:05 -05:00
disallow_idle ( ) ;
2013-09-23 14:41:52 -04:00
}
2015-09-16 15:32:59 -04:00
SessionDialog : : SessionDialog ( )
: ArdourDialog ( _ ( " Recent Sessions " ) , true , true )
, new_only ( false )
, _existing_session_chooser_used ( false ) // caller must check should_be_new
{
get_vbox ( ) - > set_spacing ( 6 ) ;
cancel_button = add_button ( Stock : : CANCEL , RESPONSE_CANCEL ) ;
open_button = add_button ( Stock : : OPEN , RESPONSE_ACCEPT ) ;
open_button - > set_sensitive ( false ) ;
setup_recent_sessions ( ) ;
get_vbox ( ) - > pack_start ( recent_scroller , true , true ) ;
get_vbox ( ) - > show_all ( ) ;
2015-10-24 13:07:19 -04:00
2015-09-16 15:32:59 -04:00
recent_scroller . show ( ) ;
int cnt = redisplay_recent_sessions ( ) ;
if ( cnt > 4 ) {
recent_scroller . set_size_request ( - 1 , 300 ) ;
2015-10-24 13:12:38 -04:00
} else {
recent_scroller . set_size_request ( - 1 , 80 ) ;
2015-09-16 15:32:59 -04:00
}
2015-10-24 13:12:38 -04:00
2022-12-12 12:17:05 -05:00
disallow_idle ( ) ;
2015-09-16 15:32:59 -04:00
}
2013-09-23 14:41:52 -04:00
SessionDialog : : ~ SessionDialog ( )
{
}
2017-08-15 23:02:26 -04:00
uint32_t
2019-10-08 23:40:14 -04:00
SessionDialog : : meta_master_bus_profile ( std : : string script_path )
2017-08-15 23:02:26 -04:00
{
if ( ! Glib : : file_test ( script_path , Glib : : FILE_TEST_EXISTS | Glib : : FILE_TEST_IS_REGULAR ) ) {
return UINT32_MAX ;
}
LuaState lua ;
lua . sandbox ( true ) ;
lua_State * L = lua . getState ( ) ;
lua . do_command (
" ardourluainfo = {} "
" function ardour (entry) "
" ardourluainfo['type'] = assert(entry['type']) "
" ardourluainfo['master_bus'] = entry['master_bus'] or 2 "
" end "
) ;
int err = - 1 ;
try {
err = lua . do_file ( script_path ) ;
} catch ( luabridge : : LuaException const & e ) {
2020-04-18 12:13:32 -04:00
# ifndef NDEBUG
cerr < < " LuaException: " < < e . what ( ) < < endl ;
# endif
PBD : : warning < < " LuaException: " < < e . what ( ) < < endmsg ;
2017-08-15 23:02:26 -04:00
err = - 1 ;
2017-08-18 19:05:08 -04:00
} catch ( . . . ) {
err = - 1 ;
2017-08-15 23:02:26 -04:00
}
if ( err ) {
return UINT32_MAX ;
}
luabridge : : LuaRef nfo = luabridge : : getGlobal ( L , " ardourluainfo " ) ;
if ( nfo . type ( ) ! = LUA_TTABLE ) {
return UINT32_MAX ;
}
if ( nfo [ " master_bus " ] . type ( ) ! = LUA_TNUMBER | | nfo [ " type " ] . type ( ) ! = LUA_TSTRING ) {
return UINT32_MAX ;
}
LuaScriptInfo : : ScriptType type = LuaScriptInfo : : str2type ( nfo [ " type " ] . cast < std : : string > ( ) ) ;
2017-08-18 14:41:35 -04:00
if ( type ! = LuaScriptInfo : : SessionInit ) {
2017-08-15 23:02:26 -04:00
return UINT32_MAX ;
}
return nfo [ " master_bus " ] . cast < uint32_t > ( ) ;
}
uint32_t
SessionDialog : : master_channel_count ( )
{
if ( use_session_template ( ) ) {
std : : string tn = session_template_name ( ) ;
if ( tn . substr ( 0 , 11 ) = = " urn:ardour: " ) {
uint32_t mc = meta_master_bus_profile ( tn . substr ( 11 ) ) ;
if ( mc ! = UINT32_MAX ) {
return mc ;
}
}
}
return 2 ;
}
2013-09-23 14:41:52 -04:00
bool
2017-08-15 23:02:26 -04:00
SessionDialog : : use_session_template ( ) const
2013-09-23 14:41:52 -04:00
{
2022-01-26 16:02:41 -05:00
if ( ! back_button - > is_sensitive ( ) & & ! new_only ) {
2017-08-23 20:08:32 -04:00
/* open session -- not create a new one */
return false ;
}
2017-08-15 23:02:26 -04:00
if ( template_chooser . get_selection ( ) - > count_selected_rows ( ) > 0 ) {
2013-09-23 14:41:52 -04:00
return true ;
}
return false ;
}
std : : string
SessionDialog : : session_template_name ( )
{
2017-08-15 23:02:26 -04:00
if ( template_chooser . get_selection ( ) - > count_selected_rows ( ) > 0 ) {
TreeIter const iter = template_chooser . get_selection ( ) - > get_selected ( ) ;
if ( iter ) {
string s = ( * iter ) [ session_template_columns . path ] ;
return s ;
}
2015-10-04 14:51:05 -04:00
}
2013-09-23 14:41:52 -04:00
return string ( ) ;
}
2019-10-08 23:48:11 -04:00
void
SessionDialog : : clear_name ( )
{
recent_session_display . get_selection ( ) - > unselect_all ( ) ;
new_name_entry . set_text ( string ( ) ) ;
}
2013-09-23 14:41:52 -04:00
std : : string
SessionDialog : : session_name ( bool & should_be_new )
{
/* Try recent session selection */
TreeIter iter = recent_session_display . get_selection ( ) - > get_selected ( ) ;
2015-10-05 10:17:49 -04:00
2013-09-23 14:41:52 -04:00
if ( iter ) {
should_be_new = false ;
2015-11-19 21:21:57 -05:00
string s = ( * iter ) [ recent_session_columns . fullpath ] ;
if ( Glib : : file_test ( s , Glib : : FILE_TEST_IS_REGULAR ) ) {
return PBD : : basename_nosuffix ( s ) ;
}
2013-09-23 14:41:52 -04:00
return ( * iter ) [ recent_session_columns . visible_name ] ;
}
if ( _existing_session_chooser_used ) {
/* existing session chosen from file chooser */
should_be_new = false ;
return existing_session_chooser . get_filename ( ) ;
} else {
should_be_new = true ;
string val = new_name_entry . get_text ( ) ;
strip_whitespace_edges ( val ) ;
return val ;
}
}
std : : string
SessionDialog : : session_folder ( )
{
/* Try recent session selection */
2015-10-05 10:17:49 -04:00
2013-09-23 14:41:52 -04:00
TreeIter iter = recent_session_display . get_selection ( ) - > get_selected ( ) ;
2015-10-05 10:17:49 -04:00
2013-09-23 14:41:52 -04:00
if ( iter ) {
2013-10-07 20:46:10 -04:00
string s = ( * iter ) [ recent_session_columns . fullpath ] ;
if ( Glib : : file_test ( s , Glib : : FILE_TEST_IS_REGULAR ) ) {
return Glib : : path_get_dirname ( s ) ;
}
return s ;
2013-09-23 14:41:52 -04:00
}
if ( _existing_session_chooser_used ) {
/* existing session chosen from file chooser */
2013-10-07 20:46:10 -04:00
return Glib : : path_get_dirname ( existing_session_chooser . get_current_folder ( ) ) ;
2013-09-23 14:41:52 -04:00
} else {
2014-06-05 12:26:16 -04:00
std : : string val = new_name_entry . get_text ( ) ;
strip_whitespace_edges ( val ) ;
std : : string legal_session_folder_name = legalize_for_path ( val ) ;
2015-01-05 23:58:39 -05:00
return Glib : : build_filename ( new_folder_chooser . get_filename ( ) , legal_session_folder_name ) ;
2013-09-23 14:41:52 -04:00
}
}
2023-09-14 13:36:10 -04:00
Temporal : : TimeDomain
SessionDialog : : session_domain ( ) const
{
return timebase_chooser . get_active_row_number ( ) = = 1 ? Temporal : : BeatTime : Temporal : : AudioTime ;
}
2015-09-16 15:32:59 -04:00
void
SessionDialog : : setup_recent_sessions ( )
{
recent_session_model = TreeStore : : create ( recent_session_columns ) ;
recent_session_model - > signal_sort_column_changed ( ) . connect ( sigc : : mem_fun ( * this , & SessionDialog : : recent_session_sort_changed ) ) ;
recent_session_display . set_model ( recent_session_model ) ;
recent_session_display . append_column ( _ ( " Session Name " ) , recent_session_columns . visible_name ) ;
recent_session_display . append_column ( _ ( " Sample Rate " ) , recent_session_columns . sample_rate ) ;
2017-09-10 16:33:12 -04:00
# ifdef MIXBUS
2017-09-20 20:00:05 -04:00
recent_session_display . append_column ( _ ( " Modified With " ) , recent_session_columns . modified_with ) ;
2017-09-10 16:33:12 -04:00
# else
2015-09-16 15:32:59 -04:00
recent_session_display . append_column ( _ ( " File Resolution " ) , recent_session_columns . disk_format ) ;
2017-09-10 16:33:12 -04:00
# endif
2015-09-16 15:32:59 -04:00
recent_session_display . append_column ( _ ( " Last Modified " ) , recent_session_columns . time_formatted ) ;
recent_session_display . set_headers_visible ( true ) ;
recent_session_display . get_selection ( ) - > set_mode ( SELECTION_SINGLE ) ;
recent_session_display . get_selection ( ) - > signal_changed ( ) . connect ( sigc : : mem_fun ( * this , & SessionDialog : : recent_session_row_selected ) ) ;
recent_scroller . add ( recent_session_display ) ;
recent_scroller . set_policy ( Gtk : : POLICY_NEVER , Gtk : : POLICY_AUTOMATIC ) ;
recent_scroller . set_shadow_type ( Gtk : : SHADOW_IN ) ;
recent_session_display . show ( ) ;
recent_session_display . signal_row_activated ( ) . connect ( sigc : : mem_fun ( * this , & SessionDialog : : recent_row_activated ) ) ;
2016-11-30 05:07:37 -05:00
recent_session_display . signal_button_press_event ( ) . connect ( sigc : : mem_fun ( * this , & SessionDialog : : recent_button_press ) , false ) ;
2015-09-16 15:32:59 -04:00
}
2013-09-23 14:41:52 -04:00
void
SessionDialog : : setup_initial_choice_box ( )
{
ic_vbox . set_spacing ( 6 ) ;
HBox * centering_hbox = manage ( new HBox ) ;
VBox * centering_vbox = manage ( new VBox ) ;
centering_vbox - > set_spacing ( 6 ) ;
Label * new_label = manage ( new Label ) ;
2013-09-23 23:13:07 -04:00
new_label - > set_markup ( string_compose ( " <span weight= \" bold \" size= \" large \" >%1</span> " , _ ( " New Session " ) ) ) ;
new_label - > set_justify ( JUSTIFY_CENTER ) ;
2013-09-23 14:41:52 -04:00
ic_new_session_button . add ( * new_label ) ;
ic_new_session_button . signal_clicked ( ) . connect ( sigc : : mem_fun ( * this , & SessionDialog : : new_session_button_clicked ) ) ;
2013-09-23 23:13:07 -04:00
Gtk : : HBox * hbox = manage ( new HBox ) ;
2013-10-08 12:18:27 -04:00
Gtk : : VBox * vbox = manage ( new VBox ) ;
2013-09-23 23:13:07 -04:00
hbox - > set_spacing ( 12 ) ;
2013-10-08 12:18:27 -04:00
vbox - > set_spacing ( 12 ) ;
2013-09-23 23:13:07 -04:00
string image_path ;
2016-05-17 07:12:05 -04:00
Searchpath rc ( ARDOUR : : ardour_data_search_path ( ) ) ;
rc . add_subdirectory_to_paths ( " resources " ) ;
if ( find_file ( rc , PROGRAM_NAME " -small-splash.png " , image_path ) ) {
2013-09-23 23:13:07 -04:00
Gtk : : Image * image ;
if ( ( image = manage ( new Gtk : : Image ( image_path ) ) ) ! = 0 ) {
hbox - > pack_start ( * image , false , false ) ;
}
}
2015-10-05 10:17:49 -04:00
2013-10-08 12:18:27 -04:00
vbox - > pack_start ( ic_new_session_button , true , true , 20 ) ;
hbox - > pack_start ( * vbox , true , true , 20 ) ;
2015-10-05 10:17:49 -04:00
2013-09-23 23:13:07 -04:00
centering_vbox - > pack_start ( * hbox , false , false ) ;
2013-09-23 14:41:52 -04:00
/* Possible update message */
if ( ARDOUR_UI : : instance ( ) - > announce_string ( ) ! = " " ) {
Box * info_box = manage ( new VBox ) ;
info_box - > set_border_width ( 12 ) ;
info_box - > set_spacing ( 6 ) ;
info_box - > pack_start ( info_scroller_label , false , false ) ;
info_scroller_count = 0 ;
info_scroller_connection = Glib : : signal_timeout ( ) . connect ( mem_fun ( * this , & SessionDialog : : info_scroller_update ) , 50 ) ;
Gtk : : Button * updates_button = manage ( new Gtk : : Button ( _ ( " Check the website for more... " ) ) ) ;
updates_button - > signal_clicked ( ) . connect ( mem_fun ( * this , & SessionDialog : : updates_button_clicked ) ) ;
2015-01-05 00:32:14 -05:00
set_tooltip ( * updates_button , _ ( " Click to open the program website in your web browser " ) ) ;
2013-09-23 14:41:52 -04:00
info_box - > pack_start ( * updates_button , false , false ) ;
2013-09-23 16:49:24 -04:00
2017-09-18 14:45:56 -04:00
info_frame . add ( * info_box ) ;
2013-09-23 16:49:24 -04:00
info_box - > show_all ( ) ;
2017-09-18 14:45:56 -04:00
info_frame . show ( ) ;
2013-09-23 14:41:52 -04:00
}
/* recent session scroller */
2015-09-16 15:32:59 -04:00
setup_recent_sessions ( ) ;
2013-09-23 14:41:52 -04:00
recent_label . set_no_show_all ( true ) ;
recent_scroller . set_no_show_all ( true ) ;
2015-09-16 12:59:04 -04:00
2015-09-16 15:32:59 -04:00
recent_label . set_markup ( string_compose ( " <span weight= \" bold \" size= \" large \" >%1</span> " , _ ( " Recent Sessions " ) ) ) ;
2015-10-05 10:17:49 -04:00
2013-09-23 14:41:52 -04:00
centering_vbox - > pack_start ( recent_label , false , false , 12 ) ;
2014-06-26 14:54:01 -04:00
centering_vbox - > pack_start ( recent_scroller , true , true ) ;
2013-09-23 14:41:52 -04:00
/* Browse button */
2015-10-05 10:17:49 -04:00
2013-09-23 14:41:52 -04:00
existing_session_chooser . set_title ( _ ( " Select session file " ) ) ;
existing_session_chooser . signal_file_set ( ) . connect ( sigc : : mem_fun ( * this , & SessionDialog : : existing_session_selected ) ) ;
existing_session_chooser . set_current_folder ( poor_mans_glob ( Config - > get_default_session_parent_dir ( ) ) ) ;
2015-10-05 10:17:49 -04:00
2013-09-23 14:41:52 -04:00
FileFilter session_filter ;
2015-01-06 02:02:31 -05:00
session_filter . add_pattern ( string_compose ( X_ ( " *%1 " ) , ARDOUR : : statefile_suffix ) ) ;
2013-09-23 14:41:52 -04:00
session_filter . set_name ( string_compose ( _ ( " %1 sessions " ) , PROGRAM_NAME ) ) ;
existing_session_chooser . add_filter ( session_filter ) ;
2016-12-27 16:25:22 -05:00
FileFilter archive_filter ;
2017-10-02 21:09:25 -04:00
archive_filter . add_pattern ( string_compose ( X_ ( " *%1 " ) , ARDOUR : : session_archive_suffix ) ) ;
2016-12-27 16:25:22 -05:00
archive_filter . set_name ( _ ( " Session Archives " ) ) ;
existing_session_chooser . add_filter ( archive_filter ) ;
2013-09-23 14:41:52 -04:00
existing_session_chooser . set_filter ( session_filter ) ;
2015-10-05 10:17:49 -04:00
2015-10-16 13:07:25 -04:00
Gtkmm2ext : : add_volume_shortcuts ( existing_session_chooser ) ;
2015-10-05 10:17:49 -04:00
2013-09-23 14:41:52 -04:00
Label * browse_label = manage ( new Label ) ;
2013-09-23 23:13:07 -04:00
browse_label - > set_markup ( string_compose ( " <span weight= \" bold \" size= \" large \" >%1</span> " , _ ( " Other Sessions " ) ) ) ;
2015-10-05 10:17:49 -04:00
2013-09-23 14:41:52 -04:00
centering_vbox - > pack_start ( * browse_label , false , false , 12 ) ;
centering_vbox - > pack_start ( existing_session_chooser , false , false ) ;
2015-11-03 02:02:22 -05:00
/* --disable plugins UI */
_disable_plugins . set_label ( _ ( " Safe Mode: Disable all Plugins " ) ) ;
2022-01-26 16:29:36 -05:00
_disable_plugins . set_can_focus ( ) ;
2015-11-03 02:02:22 -05:00
_disable_plugins . set_relief ( Gtk : : RELIEF_NORMAL ) ;
_disable_plugins . set_mode ( true ) ;
_disable_plugins . set_active ( ARDOUR : : Session : : get_disable_all_loaded_plugins ( ) ) ;
_disable_plugins . set_border_width ( 0 ) ;
_disable_plugins . signal_clicked ( ) . connect ( sigc : : mem_fun ( * this , & SessionDialog : : disable_plugins_clicked ) ) ;
centering_vbox - > pack_start ( _disable_plugins , false , false ) ;
2013-09-23 14:41:52 -04:00
/* pack it all up */
centering_hbox - > pack_start ( * centering_vbox , true , true ) ;
ic_vbox . pack_start ( * centering_hbox , true , true ) ;
ic_vbox . show_all ( ) ;
}
void
SessionDialog : : session_selected ( )
{
/* HACK HACK HACK ... change the "Apply" button label
to say " Open "
*/
Gtk : : Widget * tl = ic_vbox . get_toplevel ( ) ;
Gtk : : Window * win ;
if ( ( win = dynamic_cast < Gtk : : Window * > ( tl ) ) ! = 0 ) {
/* ::get_default_widget() is not wrapped in gtkmm */
Gtk : : Widget * def = wrap ( gtk_window_get_default_widget ( win - > gobj ( ) ) ) ;
Gtk : : Button * button ;
if ( ( button = dynamic_cast < Gtk : : Button * > ( def ) ) ! = 0 ) {
button - > set_label ( _ ( " Open " ) ) ;
}
}
}
void
SessionDialog : : new_session_button_clicked ( )
{
_existing_session_chooser_used = false ;
recent_session_display . get_selection ( ) - > unselect_all ( ) ;
get_vbox ( ) - > remove ( ic_vbox ) ;
get_vbox ( ) - > pack_start ( session_new_vbox , true , true ) ;
2020-03-24 00:40:13 -04:00
2013-09-23 14:41:52 -04:00
back_button - > set_sensitive ( true ) ;
2020-03-24 21:43:20 -04:00
setup_untitled_session ( ) ;
2013-09-23 14:41:52 -04:00
}
bool
SessionDialog : : back_button_pressed ( GdkEventButton * )
{
get_vbox ( ) - > remove ( session_new_vbox ) ;
back_button - > set_sensitive ( false ) ;
get_vbox ( ) - > pack_start ( ic_vbox ) ;
2020-02-06 15:38:02 -05:00
resize ( inital_height , inital_width ) ;
2013-09-23 14:41:52 -04:00
return true ;
}
2016-10-06 11:42:46 -04:00
bool
SessionDialog : : open_button_pressed ( GdkEventButton * ev )
{
if ( Gtkmm2ext : : Keyboard : : modifier_state_equals ( ev - > state , Gtkmm2ext : : Keyboard : : PrimaryModifier ) ) {
_disable_plugins . set_active ( ) ;
}
response ( RESPONSE_ACCEPT ) ;
return true ;
}
2020-03-24 21:43:20 -04:00
void
SessionDialog : : setup_untitled_session ( )
{
2020-03-25 12:45:00 -04:00
new_name_entry . set_text ( string_compose ( _ ( " Untitled-%1 " ) , Glib : : DateTime : : create_now_local ( ) . format ( " %F-%H-%M-%S " ) ) ) ;
2020-03-24 21:43:20 -04:00
new_name_entry . select_region ( 0 , - 1 ) ;
new_name_was_edited = false ;
back_button - > set_sensitive ( true ) ;
new_name_entry . grab_focus ( ) ;
}
2013-09-23 14:41:52 -04:00
void
SessionDialog : : populate_session_templates ( )
{
vector < TemplateInfo > templates ;
2017-08-15 23:02:26 -04:00
find_session_templates ( templates , true ) ;
2013-09-23 14:41:52 -04:00
template_model - > clear ( ) ;
2018-10-03 21:36:40 -04:00
/* Get Lua Scripts dedicated to session-setup */
LuaScriptList scripts ( LuaScripting : : instance ( ) . scripts ( LuaScriptInfo : : SessionInit ) ) ;
2017-08-18 19:32:28 -04:00
/* Add Lua Action Scripts which can also be used for session-setup */
2017-08-18 14:41:35 -04:00
LuaScriptList & as ( LuaScripting : : instance ( ) . scripts ( LuaScriptInfo : : EditorAction ) ) ;
for ( LuaScriptList : : const_iterator s = as . begin ( ) ; s ! = as . end ( ) ; + + s ) {
2018-10-03 21:36:40 -04:00
if ( ( * s ) - > subtype & LuaScriptInfo : : SessionSetup ) {
scripts . push_back ( * s ) ;
2017-08-18 14:41:35 -04:00
}
2018-10-03 21:36:40 -04:00
}
2019-07-18 09:50:34 -04:00
std : : sort ( scripts . begin ( ) , scripts . end ( ) , LuaScripting : : Sorter ( ) ) ;
2018-10-03 21:36:40 -04:00
for ( LuaScriptList : : const_iterator s = scripts . begin ( ) ; s ! = scripts . end ( ) ; + + s ) {
2017-08-18 19:32:28 -04:00
TreeModel : : Row row = * ( template_model - > append ( ) ) ;
2017-08-18 09:37:09 -04:00
row [ session_template_columns . name ] = ( * s ) - > name ;
2017-08-15 23:02:26 -04:00
row [ session_template_columns . path ] = " urn:ardour: " + ( * s ) - > path ;
row [ session_template_columns . description ] = ( * s ) - > description ;
2020-04-14 13:01:10 -04:00
row [ session_template_columns . modified_with_short ] = string_compose ( " {%1} " , _ ( " Factory Template " ) ) ;
row [ session_template_columns . modified_with_long ] = string_compose ( " {%1} " , _ ( " Factory Template " ) ) ;
2017-08-15 23:02:26 -04:00
}
//Add any "template sessions" found in the user's preferences folder
2017-08-14 17:14:42 -04:00
for ( vector < TemplateInfo > : : iterator x = templates . begin ( ) ; x ! = templates . end ( ) ; + + x ) {
TreeModel : : Row row ;
row = * ( template_model - > append ( ) ) ;
row [ session_template_columns . name ] = ( * x ) . name ;
row [ session_template_columns . path ] = ( * x ) . path ;
2017-08-15 23:02:26 -04:00
row [ session_template_columns . description ] = ( * x ) . description ;
2017-09-20 20:00:05 -04:00
row [ session_template_columns . modified_with_long ] = ( * x ) . modified_with ;
row [ session_template_columns . modified_with_short ] = ( * x ) . modified_with . substr ( 0 , ( * x ) . modified_with . find ( " " ) ) ;
2013-09-23 14:41:52 -04:00
}
2017-08-15 10:46:31 -04:00
2017-08-15 23:02:26 -04:00
//Add an explicit 'Empty Template' item
TreeModel : : Row row = * template_model - > prepend ( ) ;
row [ session_template_columns . name ] = ( _ ( " Empty Template " ) ) ;
row [ session_template_columns . path ] = string ( ) ;
2019-04-09 18:22:39 -04:00
row [ session_template_columns . description ] = _ ( " An empty session with factory default settings. \n \n Select this option if you are importing files to mix. " ) ;
2021-11-30 13:50:59 -05:00
row [ session_template_columns . modified_with_short ] = ( " " ) ;
row [ session_template_columns . modified_with_long ] = ( " " ) ;
2017-08-15 10:46:31 -04:00
2017-08-15 23:02:26 -04:00
//auto-select the first item in the list
Gtk : : TreeModel : : Row first = template_model - > children ( ) [ 0 ] ;
if ( first ) {
template_chooser . get_selection ( ) - > select ( first ) ;
2017-08-15 10:46:31 -04:00
}
2013-09-23 14:41:52 -04:00
}
void
SessionDialog : : setup_new_session_page ( )
{
2017-08-15 23:02:26 -04:00
session_new_vbox . set_border_width ( 8 ) ;
session_new_vbox . set_spacing ( 8 ) ;
2013-09-23 14:41:52 -04:00
2017-08-15 23:02:26 -04:00
Label * name_label = manage ( new Label ) ;
name_label - > set_text ( _ ( " Session name: " ) ) ;
2013-09-23 14:41:52 -04:00
2017-08-15 23:02:26 -04:00
HBox * name_hbox = manage ( new HBox ) ;
name_hbox - > set_spacing ( 8 ) ;
name_hbox - > pack_start ( * name_label , false , true ) ;
name_hbox - > pack_start ( new_name_entry , true , true ) ;
2013-09-23 14:41:52 -04:00
2020-03-24 02:00:33 -04:00
new_name_entry . signal_key_press_event ( ) . connect ( sigc : : mem_fun ( * this , & SessionDialog : : new_name_edited ) , false ) ;
2013-09-23 14:41:52 -04:00
new_name_entry . signal_changed ( ) . connect ( sigc : : mem_fun ( * this , & SessionDialog : : new_name_changed ) ) ;
new_name_entry . signal_activate ( ) . connect ( sigc : : mem_fun ( * this , & SessionDialog : : new_name_activated ) ) ;
2017-08-15 23:02:26 -04:00
//Folder location for the new session
Label * new_folder_label = manage ( new Label ) ;
new_folder_label - > set_text ( _ ( " Create session folder in: " ) ) ;
HBox * folder_box = manage ( new HBox ) ;
folder_box - > set_spacing ( 8 ) ;
folder_box - > pack_start ( * new_folder_label , false , false ) ;
folder_box - > pack_start ( new_folder_chooser , true , true ) ;
2013-09-23 14:41:52 -04:00
2019-10-09 22:51:14 -04:00
if ( ARDOUR_UI : : instance ( ) - > the_session ( ) ) {
2013-09-23 14:41:52 -04:00
// point the new session file chooser at the parent directory of the current session
string session_parent_dir = Glib : : path_get_dirname ( ARDOUR_UI : : instance ( ) - > the_session ( ) - > path ( ) ) ;
new_folder_chooser . set_current_folder ( session_parent_dir ) ;
string default_session_folder = poor_mans_glob ( Config - > get_default_session_parent_dir ( ) ) ;
try {
/* add_shortcut_folder throws an exception if the folder being added already has a shortcut */
new_folder_chooser . add_shortcut_folder ( default_session_folder ) ;
}
catch ( Glib : : Error & e ) {
std : : cerr < < " new_folder_chooser.add_shortcut_folder ( " < < default_session_folder < < " ) threw Glib::Error " < < e . what ( ) < < std : : endl ;
}
} else {
new_folder_chooser . set_current_folder ( poor_mans_glob ( Config - > get_default_session_parent_dir ( ) ) ) ;
}
new_folder_chooser . show ( ) ;
new_folder_chooser . set_title ( _ ( " Select folder for session " ) ) ;
2015-10-16 13:07:25 -04:00
Gtkmm2ext : : add_volume_shortcuts ( new_folder_chooser ) ;
2013-09-23 14:41:52 -04:00
2023-09-14 13:36:10 -04:00
//Timebase for the new session
Label * session_domain_label = manage ( new Label ) ;
session_domain_label - > set_text ( _ ( " Default Time Domain: " ) ) ;
HBox * timebase_box = manage ( new HBox ) ;
timebase_box - > set_spacing ( 8 ) ;
timebase_box - > pack_start ( * session_domain_label , false , false ) ;
timebase_box - > pack_start ( timebase_chooser , true , true ) ;
timebase_chooser . append ( _ ( " Audio Time " ) ) ;
timebase_chooser . append ( _ ( " Beat Time " ) ) ;
# ifdef MIXBUS
timebase_chooser . set_active ( 1 ) ;
# else
timebase_chooser . set_active ( 0 ) ;
# endif
2017-08-15 23:02:26 -04:00
//Template & Template Description area
HBox * template_hbox = manage ( new HBox ) ;
2017-08-15 19:13:00 -04:00
2017-08-15 23:02:26 -04:00
//if the "template override" is provided, don't give the user any template selections (?)
2019-07-18 10:16:11 -04:00
if ( load_template_override . empty ( ) ) {
2017-08-15 23:02:26 -04:00
template_hbox - > set_spacing ( 8 ) ;
2017-08-16 11:17:30 -04:00
Gtk : : ScrolledWindow * template_scroller = manage ( new Gtk : : ScrolledWindow ( ) ) ;
template_scroller - > set_policy ( Gtk : : POLICY_NEVER , Gtk : : POLICY_AUTOMATIC ) ;
template_scroller - > add ( template_chooser ) ;
2017-08-17 14:52:16 -04:00
2017-08-16 11:17:30 -04:00
Gtk : : ScrolledWindow * desc_scroller = manage ( new Gtk : : ScrolledWindow ( ) ) ;
desc_scroller - > set_policy ( Gtk : : POLICY_NEVER , Gtk : : POLICY_AUTOMATIC ) ;
desc_scroller - > add ( template_desc ) ;
2017-08-17 14:52:16 -04:00
template_hbox - > pack_start ( * template_scroller , true , true ) ;
2017-08-16 11:17:30 -04:00
2017-09-18 14:45:56 -04:00
template_desc_frame . set_name ( X_ ( " TextHighlightFrame " ) ) ;
template_desc_frame . add ( * desc_scroller ) ;
template_hbox - > pack_start ( template_desc_frame , true , true ) ;
2017-08-15 23:02:26 -04:00
}
2017-08-15 10:45:47 -04:00
2017-08-15 23:02:26 -04:00
//template_desc is the textview that displays the currently selected template's description
template_desc . set_editable ( false ) ;
template_desc . set_wrap_mode ( Gtk : : WRAP_WORD ) ;
2017-08-17 14:52:16 -04:00
template_desc . set_size_request ( 300 , 400 ) ;
2017-08-15 23:02:26 -04:00
template_desc . set_name ( X_ ( " TextOnBackground " ) ) ;
template_desc . set_border_width ( 6 ) ;
2017-08-15 19:13:00 -04:00
2017-08-15 23:02:26 -04:00
//template_chooser is the treeview showing available templates
template_model = TreeStore : : create ( session_template_columns ) ;
2017-08-14 17:14:42 -04:00
template_chooser . set_model ( template_model ) ;
2017-08-15 23:02:26 -04:00
template_chooser . append_column ( _ ( " Template " ) , session_template_columns . name ) ;
2017-08-17 10:47:27 -04:00
# ifdef MIXBUS
2017-09-20 20:00:05 -04:00
template_chooser . append_column ( _ ( " Modified With " ) , session_template_columns . modified_with_short ) ;
2017-08-17 10:47:27 -04:00
# endif
2017-08-15 23:02:26 -04:00
template_chooser . set_headers_visible ( true ) ;
template_chooser . get_selection ( ) - > set_mode ( SELECTION_SINGLE ) ;
template_chooser . get_selection ( ) - > signal_changed ( ) . connect ( sigc : : mem_fun ( * this , & SessionDialog : : template_row_selected ) ) ;
template_chooser . set_sensitive ( true ) ;
2018-11-01 18:20:50 -04:00
if ( UIConfiguration : : instance ( ) . get_use_tooltips ( ) ) {
template_chooser . set_tooltip_column ( 4 ) ; // modified_with_long
}
2013-09-23 14:41:52 -04:00
2017-08-16 11:17:30 -04:00
session_new_vbox . pack_start ( * template_hbox , true , true ) ;
2017-08-15 23:02:26 -04:00
session_new_vbox . pack_start ( * folder_box , false , true ) ;
2023-09-14 13:36:10 -04:00
session_new_vbox . pack_start ( * timebase_box , false , true ) ;
2017-08-15 23:02:26 -04:00
session_new_vbox . pack_start ( * name_hbox , false , true ) ;
2013-09-23 14:41:52 -04:00
session_new_vbox . show_all ( ) ;
}
2020-03-24 02:00:33 -04:00
bool
SessionDialog : : new_name_edited ( GdkEventKey * ev )
{
switch ( ev - > keyval ) {
case GDK_KP_Enter :
case GDK_3270_Enter :
case GDK_Return :
break ;
default :
new_name_was_edited = true ;
}
return false ;
}
2020-06-09 14:30:10 -04:00
static bool is_invalid_session_char ( char c )
{
/* see also Session::session_name_is_legal */
return iscntrl ( c ) | | c = = ' / ' | | c = = ' \\ ' | | c = = ' : ' | | c = = ' ; ' ;
}
2013-09-23 14:41:52 -04:00
void
SessionDialog : : new_name_changed ( )
{
2020-06-09 14:30:10 -04:00
std : : string new_name = new_name_entry . get_text ( ) ;
std : : string const & illegal = Session : : session_name_is_legal ( new_name ) ;
if ( ! illegal . empty ( ) ) {
ArdourMessageDialog msg ( string_compose ( _ ( " To ensure compatibility with various systems \n session names may not contain a '%1' character " ) , illegal ) ) ;
msg . run ( ) ;
new_name . erase ( remove_if ( new_name . begin ( ) , new_name . end ( ) , is_invalid_session_char ) , new_name . end ( ) ) ;
new_name_entry . set_text ( new_name ) ;
}
2013-09-23 14:41:52 -04:00
if ( ! new_name_entry . get_text ( ) . empty ( ) ) {
session_selected ( ) ;
open_button - > set_sensitive ( true ) ;
} else {
open_button - > set_sensitive ( false ) ;
}
}
void
SessionDialog : : new_name_activated ( )
{
response ( RESPONSE_ACCEPT ) ;
}
int
SessionDialog : : redisplay_recent_sessions ( )
{
std : : vector < std : : string > session_directories ;
2015-09-16 09:47:29 -04:00
RecentSessionsSorter cmp ;
2013-09-23 14:41:52 -04:00
recent_session_display . set_model ( Glib : : RefPtr < TreeModel > ( 0 ) ) ;
recent_session_model - > clear ( ) ;
ARDOUR : : RecentSessions rs ;
ARDOUR : : read_recent_sessions ( rs ) ;
if ( rs . empty ( ) ) {
recent_session_display . set_model ( recent_session_model ) ;
return 0 ;
}
2015-09-16 12:21:00 -04:00
2015-09-16 09:47:29 -04:00
// sort them alphabetically
sort ( rs . begin ( ) , rs . end ( ) , cmp ) ;
2013-09-23 14:41:52 -04:00
for ( ARDOUR : : RecentSessions : : iterator i = rs . begin ( ) ; i ! = rs . end ( ) ; + + i ) {
session_directories . push_back ( ( * i ) . second ) ;
}
2015-10-05 10:17:49 -04:00
2013-09-23 14:41:52 -04:00
int session_snapshot_count = 0 ;
2019-10-10 17:24:49 -04:00
for ( vector < std : : string > : : const_iterator i = session_directories . begin ( ) ; i ! = session_directories . end ( ) ; + + i ) {
2013-09-23 14:41:52 -04:00
2013-09-23 21:36:13 -04:00
string dirname = * i ;
2013-09-23 14:41:52 -04:00
/* remove any trailing / */
2020-06-08 10:38:29 -04:00
if ( dirname . empty ( ) ) {
continue ;
}
2013-09-23 21:36:13 -04:00
if ( dirname [ dirname . length ( ) - 1 ] = = ' / ' ) {
dirname = dirname . substr ( 0 , dirname . length ( ) - 1 ) ;
2013-09-23 14:41:52 -04:00
}
/* check whether session still exists */
2013-09-23 21:36:13 -04:00
if ( ! Glib : : file_test ( dirname . c_str ( ) , Glib : : FILE_TEST_EXISTS ) ) {
2013-09-23 14:41:52 -04:00
/* session doesn't exist */
continue ;
}
/* now get available states for this session */
2023-06-07 11:37:40 -04:00
vector < string > state_file_names = Session : : possible_states ( dirname ) ;
2013-09-23 14:41:52 -04:00
2013-09-23 21:36:13 -04:00
if ( state_file_names . empty ( ) ) {
2023-06-07 11:37:40 -04:00
/* no state file? */
2013-09-23 21:36:13 -04:00
continue ;
}
float sr ;
SampleFormat sf ;
2017-01-20 18:48:47 -05:00
std : : string program_version ;
2015-11-19 21:21:57 -05:00
std : : string state_file_basename ;
if ( state_file_names . size ( ) > 1 ) {
state_file_basename = Session : : get_snapshot_from_instant ( dirname ) ;
std : : string s = Glib : : build_filename ( dirname , state_file_basename + statefile_suffix ) ;
if ( ! Glib : : file_test ( s , Glib : : FILE_TEST_IS_REGULAR ) ) {
state_file_basename = " " ;
}
}
if ( state_file_basename . empty ( ) ) {
state_file_basename = state_file_names . front ( ) ;
}
2014-06-06 08:25:13 -04:00
std : : string s = Glib : : build_filename ( dirname , state_file_basename + statefile_suffix ) ;
2013-09-23 21:36:13 -04:00
2017-08-17 12:52:07 -04:00
int err = Session : : get_info_from_path ( s , sr , sf , program_version ) ;
if ( err < 0 ) {
// XML cannot be parsed, or unsuppored version
continue ;
}
2015-09-15 19:23:42 -04:00
GStatBuf gsb ;
g_stat ( s . c_str ( ) , & gsb ) ;
2017-08-17 12:52:07 -04:00
Gtk : : TreeModel : : Row row = * ( recent_session_model - > append ( ) ) ;
2015-11-19 21:21:57 -05:00
row [ recent_session_columns . fullpath ] = s ;
2015-09-15 19:23:42 -04:00
row [ recent_session_columns . time_modified ] = gsb . st_mtime ;
2013-09-23 21:36:13 -04:00
2017-08-17 12:52:07 -04:00
if ( err = = 0 ) {
2013-09-23 21:36:13 -04:00
row [ recent_session_columns . sample_rate ] = rate_as_string ( sr ) ;
switch ( sf ) {
case FormatFloat :
2015-12-05 19:00:20 -05:00
row [ recent_session_columns . disk_format ] = _ ( " 32-bit float " ) ;
2013-09-23 21:36:13 -04:00
break ;
case FormatInt24 :
2015-12-05 19:00:20 -05:00
row [ recent_session_columns . disk_format ] = _ ( " 24-bit " ) ;
2013-09-23 21:36:13 -04:00
break ;
case FormatInt16 :
2015-12-05 19:00:20 -05:00
row [ recent_session_columns . disk_format ] = _ ( " 16-bit " ) ;
2013-09-23 21:36:13 -04:00
break ;
}
} else {
row [ recent_session_columns . sample_rate ] = " ?? " ;
row [ recent_session_columns . disk_format ] = " -- " ;
}
2017-01-20 18:48:47 -05:00
if ( program_version . empty ( ) ) {
2017-01-20 12:16:32 -05:00
row [ recent_session_columns . tip ] = Gtkmm2ext : : markup_escape_text ( dirname ) ;
} else {
2017-01-20 18:48:47 -05:00
row [ recent_session_columns . tip ] = Gtkmm2ext : : markup_escape_text ( dirname + " \n " + string_compose ( _ ( " Last modified with: %1 " ) , program_version ) ) ;
2017-09-20 20:00:05 -04:00
row [ recent_session_columns . modified_with ] = program_version ;
2017-01-20 12:16:32 -05:00
}
2013-09-23 14:41:52 -04:00
+ + session_snapshot_count ;
if ( state_file_names . size ( ) > 1 ) {
2014-06-06 08:25:13 -04:00
// multiple session files in the session directory - show the directory name.
// if there's not a session file with the same name as the session directory,
// opening the parent item will fail, but expanding it will show the session
// files that actually exist, and the right one can then be opened.
row [ recent_session_columns . visible_name ] = Glib : : path_get_basename ( dirname ) ;
2015-09-16 11:14:10 -04:00
int64_t most_recent = 0 ;
2013-09-23 14:41:52 -04:00
// add the children
2017-01-21 07:00:07 -05:00
int kidcount = 0 ;
2013-09-23 21:36:13 -04:00
for ( std : : vector < std : : string > : : iterator i2 = state_file_names . begin ( ) ; i2 ! = state_file_names . end ( ) ; + + i2 ) {
2013-09-23 14:41:52 -04:00
2015-09-15 19:21:10 -04:00
s = Glib : : build_filename ( dirname , * i2 + statefile_suffix ) ;
2013-09-23 14:41:52 -04:00
Gtk : : TreeModel : : Row child_row = * ( recent_session_model - > append ( row . children ( ) ) ) ;
2015-10-05 10:17:49 -04:00
2013-09-23 14:41:52 -04:00
child_row [ recent_session_columns . visible_name ] = * i2 ;
2015-09-15 19:21:10 -04:00
child_row [ recent_session_columns . fullpath ] = s ;
2017-01-21 06:51:10 -05:00
child_row [ recent_session_columns . tip ] = Gtkmm2ext : : markup_escape_text ( dirname ) ;
2015-09-15 19:23:42 -04:00
g_stat ( s . c_str ( ) , & gsb ) ;
2015-09-16 11:14:10 -04:00
child_row [ recent_session_columns . time_modified ] = gsb . st_mtime ;
Glib : : DateTime gdt ( Glib : : DateTime : : create_now_local ( gsb . st_mtime ) ) ;
2015-09-16 13:01:13 -04:00
child_row [ recent_session_columns . time_formatted ] = gdt . format ( " %F %H:%M " ) ;
2015-09-16 11:14:10 -04:00
if ( gsb . st_mtime > most_recent ) {
most_recent = gsb . st_mtime ;
}
2017-01-21 07:00:07 -05:00
if ( + + kidcount < 5 ) {
// parse "modified with" for the first 5 snapshots
if ( Session : : get_info_from_path ( s , sr , sf , program_version ) = = 0 ) {
2016-12-08 14:33:04 -05:00
#if 0
2017-01-21 07:00:07 -05:00
child_row [ recent_session_columns . sample_rate ] = rate_as_string ( sr ) ;
switch ( sf ) {
2017-08-15 23:02:26 -04:00
case FormatFloat :
child_row [ recent_session_columns . disk_format ] = _ ( " 32-bit float " ) ;
break ;
case FormatInt24 :
child_row [ recent_session_columns . disk_format ] = _ ( " 24-bit " ) ;
break ;
case FormatInt16 :
child_row [ recent_session_columns . disk_format ] = _ ( " 16-bit " ) ;
break ;
2017-01-21 07:00:07 -05:00
}
# else
child_row [ recent_session_columns . sample_rate ] = " " ;
child_row [ recent_session_columns . disk_format ] = " " ;
# endif
} else {
child_row [ recent_session_columns . sample_rate ] = " ?? " ;
child_row [ recent_session_columns . disk_format ] = " -- " ;
}
if ( ! program_version . empty ( ) ) {
child_row [ recent_session_columns . tip ] = Gtkmm2ext : : markup_escape_text ( string_compose ( _ ( " Last modified with: %1 " ) , program_version ) ) ;
2013-09-23 21:36:13 -04:00
}
} else {
2017-01-21 07:00:07 -05:00
child_row [ recent_session_columns . sample_rate ] = " " ;
child_row [ recent_session_columns . disk_format ] = " " ;
2013-09-23 21:36:13 -04:00
}
2013-09-23 14:41:52 -04:00
+ + session_snapshot_count ;
}
2015-09-16 11:14:10 -04:00
assert ( most_recent > = row [ recent_session_columns . time_modified ] ) ;
row [ recent_session_columns . time_modified ] = most_recent ;
2014-06-06 08:25:13 -04:00
} else {
// only a single session file in the directory - show its actual name.
row [ recent_session_columns . visible_name ] = state_file_basename ;
2013-09-23 14:41:52 -04:00
}
2015-09-16 11:14:10 -04:00
Glib : : DateTime gdt ( Glib : : DateTime : : create_now_local ( row [ recent_session_columns . time_modified ] ) ) ;
2015-09-16 13:01:13 -04:00
row [ recent_session_columns . time_formatted ] = gdt . format ( " %F %H:%M " ) ;
2013-09-23 14:41:52 -04:00
}
2018-11-01 18:20:50 -04:00
if ( UIConfiguration : : instance ( ) . get_use_tooltips ( ) ) {
recent_session_display . set_tooltip_column ( 1 ) ; // recent_session_columns.tip
}
2013-09-23 14:41:52 -04:00
recent_session_display . set_model ( recent_session_model ) ;
2015-09-16 11:33:50 -04:00
// custom sort
Gtk : : TreeView : : Column * pColumn ;
if ( ( pColumn = recent_session_display . get_column ( 0 ) ) ) { // name
pColumn - > set_sort_column ( recent_session_columns . visible_name ) ;
}
if ( ( pColumn = recent_session_display . get_column ( 3 ) ) ) { // date
pColumn - > set_sort_column ( recent_session_columns . time_modified ) ; // unixtime
}
2015-09-16 17:11:54 -04:00
int32_t sort = UIConfiguration : : instance ( ) . get_recent_session_sort ( ) ;
2015-09-16 13:30:41 -04:00
if ( abs ( sort ) ! = 1 + recent_session_columns . visible_name . index ( ) & &
abs ( sort ) ! = 1 + recent_session_columns . time_modified . index ( ) ) {
sort = 1 + recent_session_columns . visible_name . index ( ) ;
}
recent_session_model - > set_sort_column ( abs ( sort ) - 1 , sort < 0 ? Gtk : : SORT_DESCENDING : Gtk : : SORT_ASCENDING ) ;
2015-09-16 12:59:04 -04:00
2013-09-23 14:41:52 -04:00
return session_snapshot_count ;
}
2015-09-16 12:59:04 -04:00
void
SessionDialog : : recent_session_sort_changed ( )
{
int column ;
SortType order ;
if ( recent_session_model - > get_sort_column_id ( column , order ) ) {
2015-09-16 13:30:41 -04:00
int32_t sort = ( column + 1 ) * ( order = = Gtk : : SORT_DESCENDING ? - 1 : 1 ) ;
2015-09-16 17:11:54 -04:00
if ( sort ! = UIConfiguration : : instance ( ) . get_recent_session_sort ( ) ) {
UIConfiguration : : instance ( ) . set_recent_session_sort ( sort ) ;
2015-09-16 12:59:04 -04:00
}
}
}
2013-09-23 14:41:52 -04:00
void
SessionDialog : : recent_session_row_selected ( )
{
if ( recent_session_display . get_selection ( ) - > count_selected_rows ( ) > 0 ) {
open_button - > set_sensitive ( true ) ;
session_selected ( ) ;
} else {
open_button - > set_sensitive ( false ) ;
}
}
2017-08-14 17:14:42 -04:00
void
2017-08-15 23:02:26 -04:00
SessionDialog : : template_row_selected ( )
2017-08-14 17:14:42 -04:00
{
2017-08-15 23:02:26 -04:00
if ( template_chooser . get_selection ( ) - > count_selected_rows ( ) > 0 ) {
TreeIter iter = template_chooser . get_selection ( ) - > get_selected ( ) ;
2017-08-15 19:13:00 -04:00
2017-08-15 23:02:26 -04:00
if ( iter ) {
string s = ( * iter ) [ session_template_columns . description ] ;
template_desc . get_buffer ( ) - > set_text ( s ) ;
}
2017-08-14 17:14:42 -04:00
}
}
2013-09-23 14:41:52 -04:00
void
SessionDialog : : recent_row_activated ( const Gtk : : TreePath & , Gtk : : TreeViewColumn * )
{
response ( RESPONSE_ACCEPT ) ;
}
2016-11-30 05:07:37 -05:00
bool
SessionDialog : : recent_button_press ( GdkEventButton * ev )
{
if ( ( ev - > type = = GDK_BUTTON_PRESS ) & & ( ev - > button = = 3 ) ) {
TreeModel : : Path path ;
TreeViewColumn * column ;
int cellx , celly ;
if ( recent_session_display . get_path_at_pos ( ( int ) ev - > x , ( int ) ev - > y , path , column , cellx , celly ) ) {
Glib : : RefPtr < Gtk : : TreeView : : Selection > selection = recent_session_display . get_selection ( ) ;
if ( selection ) {
selection - > unselect_all ( ) ;
selection - > select ( path ) ;
}
}
if ( recent_session_display . get_selection ( ) - > count_selected_rows ( ) > 0 ) {
recent_context_mennu ( ev ) ;
}
}
return false ;
}
void
SessionDialog : : recent_context_mennu ( GdkEventButton * ev )
{
using namespace Gtk : : Menu_Helpers ;
TreeIter iter = recent_session_display . get_selection ( ) - > get_selected ( ) ;
assert ( iter ) ;
string s = ( * iter ) [ recent_session_columns . fullpath ] ;
if ( Glib : : file_test ( s , Glib : : FILE_TEST_IS_REGULAR ) ) {
s = Glib : : path_get_dirname ( s ) ;
}
if ( ! Glib : : file_test ( s , Glib : : FILE_TEST_IS_DIR ) ) {
return ;
}
2017-04-28 08:32:37 -04:00
Gtk : : TreeModel : : Path tpath = recent_session_model - > get_path ( iter ) ;
const bool is_child = tpath . up ( ) & & tpath . up ( ) ;
2019-03-07 11:02:12 -05:00
Gtk : : Menu * m = ARDOUR_UI : : instance ( ) - > shared_popup_menu ( ) ;
2016-11-30 05:07:37 -05:00
MenuList & items = m - > items ( ) ;
2017-04-28 08:33:06 -04:00
items . push_back ( MenuElem ( s , sigc : : bind ( sigc : : hide_return ( sigc : : ptr_fun ( & PBD : : open_folder ) ) , s ) ) ) ;
2017-04-28 08:32:37 -04:00
if ( ! is_child ) {
items . push_back ( SeparatorElem ( ) ) ;
items . push_back ( MenuElem ( _ ( " Remove session from recent list " ) , sigc : : mem_fun ( * this , & SessionDialog : : recent_remove_selected ) ) ) ;
}
2016-11-30 05:07:37 -05:00
m - > popup ( ev - > button , ev - > time ) ;
}
void
SessionDialog : : recent_remove_selected ( )
{
TreeIter iter = recent_session_display . get_selection ( ) - > get_selected ( ) ;
assert ( iter ) ;
string s = ( * iter ) [ recent_session_columns . fullpath ] ;
if ( Glib : : file_test ( s , Glib : : FILE_TEST_IS_REGULAR ) ) {
s = Glib : : path_get_dirname ( s ) ;
}
ARDOUR : : remove_recent_sessions ( s ) ;
redisplay_recent_sessions ( ) ;
}
2015-11-03 02:02:22 -05:00
void
SessionDialog : : disable_plugins_clicked ( )
{
ARDOUR : : Session : : set_disable_all_loaded_plugins ( _disable_plugins . get_active ( ) ) ;
}
2013-09-23 14:41:52 -04:00
void
SessionDialog : : existing_session_selected ( )
{
_existing_session_chooser_used = true ;
2014-05-16 17:16:03 -04:00
recent_session_display . get_selection ( ) - > unselect_all ( ) ;
2013-09-23 14:41:52 -04:00
/* mark this sensitive in case we come back here after a failed open
* attempt and the user has hacked up the fix . sigh .
*/
open_button - > set_sensitive ( true ) ;
response ( RESPONSE_ACCEPT ) ;
}
void
SessionDialog : : updates_button_clicked ( )
{
//now open a browser window so user can see more
PBD : : open_uri ( Config - > get_updates_url ( ) ) ;
}
bool
SessionDialog : : info_scroller_update ( )
{
info_scroller_count + + ;
char buf [ 512 ] ;
snprintf ( buf , std : : min ( info_scroller_count , sizeof ( buf ) - 1 ) , " %s " , ARDOUR_UI : : instance ( ) - > announce_string ( ) . c_str ( ) ) ;
buf [ info_scroller_count ] = 0 ;
info_scroller_label . set_text ( buf ) ;
info_scroller_label . show ( ) ;
if ( info_scroller_count > ARDOUR_UI : : instance ( ) - > announce_string ( ) . length ( ) ) {
info_scroller_connection . disconnect ( ) ;
}
return true ;
}
bool
SessionDialog : : on_delete_event ( GdkEventAny * ev )
{
response ( RESPONSE_CANCEL ) ;
return ArdourDialog : : on_delete_event ( ev ) ;
}
2019-10-09 22:51:14 -04:00
void
SessionDialog : : set_provided_session ( string const & name , string const & path )
{
/* Note: path is required to be the full path to the session file, not
just the folder name
*/
new_name_entry . set_text ( name ) ;
existing_session_chooser . set_current_folder ( Glib : : path_get_dirname ( path ) ) ;
}