summaryrefslogtreecommitdiff
path: root/src/FolderSync/Banshee.FolderSync/FolderSyncView.cs
blob: 4d32012ccb43619ea5efa6d078c0b5f9b1e5671d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
//
// Copyright (c) 2011 Timo Dörr <timo.doerr@latecrew.de>
// 
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
// 
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
// 
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading;

using Gtk;
using Mono.Addins;

using Hyena.Widgets;
using Banshee.Sources.Gui;

namespace Banshee.FolderSync
{
    public class OptionsModel
    {
        public bool OverwriteExisting;
        public bool CreateM3u;
        public uint SubfolderDepth;
        public string TargetFolder;
        public List<Playlist> SelectedPlaylists;
    }

    public class FolderSyncView : Frame
    {
        public List<Playlist> SelectedPlaylists;

        public OptionsModel GetOptions ()
        {
            var options = new OptionsModel {
                 OverwriteExisting = overwrite_existing.Active,
                 CreateM3u = create_m3u.Active,
                 SubfolderDepth = 0,
                 TargetFolder = target_chooser.Uri
             };
            // if activated, we create subfolder until given depth
            if (create_subfolders.Active)
                options.SubfolderDepth = (uint)subfolder_depth.Value;

            // make sure target always has ending directory seperator '/'
            if (options.TargetFolder.Last () != System.IO.Path.DirectorySeparatorChar)
                options.TargetFolder += System.IO.Path.DirectorySeparatorChar;

            // get the currently user-selected playlists
            options.SelectedPlaylists = new List<Playlist> ();
            Gtk.TreeIter iter;
            Gtk.TreeModel model;
            var tree_paths = playlist_tree.Selection.GetSelectedRows (out model);
            foreach (var path in tree_paths) {
                model.GetIter (out iter, path);
                Hyena.Log.DebugFormat ("Selected Playlist: ID {0}, Name: {1}", model.GetValue (iter, 0),
                     model.GetValue (iter, 1));

                options.SelectedPlaylists.Add (new Playlist ((uint)model.GetValue (iter, 0)));
            }
            return options;
        }

        public Gtk.ProgressBar Progress = new Gtk.ProgressBar () {
            Orientation = ProgressBarOrientation.LeftToRight, DoubleBuffered = true };
        public Gtk.Button StartSyncButton = new Button () {
            Label = AddinManager.CurrentLocalizer.GetString("Start sync") };

        // the liststore is populated from outside so have it public
        // store PlaylistID and PlaylistName
        public Gtk.ListStore PlaylistStore = new Gtk.ListStore (typeof(uint), typeof(string));
        Gtk.TreeView playlist_tree = new Gtk.TreeView ();
        Gtk.FileChooserButton target_chooser = new Gtk.FileChooserButton (
            AddinManager.CurrentLocalizer.GetString ("Choose target sync folder"),
            FileChooserAction.SelectFolder);
        Gtk.CheckButton create_m3u =
            new Gtk.CheckButton (AddinManager.CurrentLocalizer.GetString ("Create M3U Playlist"));
        Gtk.CheckButton overwrite_existing =
            new Gtk.CheckButton (AddinManager.CurrentLocalizer.GetString ("Overwrite existing files"));
        Gtk.CheckButton create_subfolders =
            new Gtk.CheckButton (AddinManager.CurrentLocalizer.GetString ("Create subfolders"));
        Gtk.SpinButton subfolder_depth = new Gtk.SpinButton (0f, 10f, 1f) {
            Text = AddinManager.CurrentLocalizer.GetString("Subfolder depth"),
            Sensitive = false
        };

#region private fields
        Gtk.VBox vbox_main = new VBox (false, 1);
        // hbox for filechooser & label
        Gtk.HBox hbox_chooser = new HBox (false, 1);
        Gtk.HPaned main_hpane = new Gtk.HPaned ();
        // hbox for subfolder depth
        Gtk.HBox hbox_subfolder = new HBox (false, 1);
        Gtk.VBox vbox_folder_and_option = new VBox (false, 1);
        Gtk.VBox vbox_checkbox = new VBox (false, 1);
        Gtk.Frame options_frame = new Gtk.Frame (AddinManager.CurrentLocalizer.GetString ("Options")) {
            ShadowType = ShadowType.Out };
        Gtk.Alignment frame_alignment = new Gtk.Alignment (0.5f, 0.5f, 1.0f, 1.0f);
        Gtk.Alignment startbutton_alignment = new Gtk.Alignment (0.25f, 0.25f, 1.0f, 1.0f);
#endregion

        public void Reload ()
        {
            Progress.Fraction = 0f;
            Progress.Text = null;
            playlist_tree.Model = PlaylistStore;
            // FIXME find a better way
            // rebind the model to force refreshing
            Gtk.Main.IterationDo (false);
        }

        public FolderSyncView ()
        {
            vbox_main.PackStart (main_hpane, true, true, 1);
            vbox_main.PackStart (Progress, false, false, 1);
            var frame = new Hyena.Widgets.ScrolledWindow ();
            frame.AddWithFrame (playlist_tree);
            main_hpane.Pack1 (frame, true, true);
            // right hand side is folder select and options
            //hbox_main.PackStart (vbox_folder_and_option, true, true, 0);
            main_hpane.Pack2 (vbox_folder_and_option, true, true);
            hbox_chooser.PackStart (
                new Gtk.Label (AddinManager.CurrentLocalizer.GetString ("Sync to folder:")),
                false, false, 1);
            hbox_chooser.PackStart (target_chooser, true, true, 1);
            vbox_folder_and_option.PackStart (hbox_chooser, false, false, 1);
            vbox_folder_and_option.PackStart (options_frame, false, false, 1);

            options_frame.Add (frame_alignment);

            frame_alignment.Add (vbox_checkbox);
            vbox_checkbox.PackStart (create_m3u, true, true, 1);
            vbox_checkbox.PackStart (overwrite_existing, true, true, 1);
            vbox_checkbox.PackStart (hbox_subfolder, true, true, 1);
            hbox_subfolder.PackStart (create_subfolders, true, true, 1);
            hbox_subfolder.PackStart (
                new Gtk.Label (AddinManager.CurrentLocalizer.GetString ("Subfolder depth") + ":"), true, true, 1);
            hbox_subfolder.PackStart (subfolder_depth, true, true, 1);

            subfolder_depth.Value = 1;
            create_subfolders.Clicked += delegate(object sender, EventArgs e) {
                subfolder_depth.Sensitive = create_subfolders.Active;
            };

            startbutton_alignment.Add (StartSyncButton);
            vbox_folder_and_option.PackStart (startbutton_alignment, false, false, 0);

            Add (vbox_main);

            // PLAYLIST TREEVIEW stuff
            // connect data model to the TreeView
            playlist_tree.Model = PlaylistStore;
            playlist_tree.Selection.Mode = Gtk.SelectionMode.Multiple;

            // new column & renderer for the playlists
            var playlist_column = new TreeViewColumn ();
            var playlist_cell_renderer = new Gtk.CellRendererText ();
            playlist_column.Title = "Playlists";
            // the the cell renderer, set to type text, and choose 1st position
            // from the model (counting starts on 0)
            playlist_column.PackStart (playlist_cell_renderer, true);
            playlist_column.AddAttribute (playlist_cell_renderer, "text", 1);
            var select_column = new TreeViewColumn ();
            var select_cell_renderer = new Gtk.CellRendererToggle ();
            select_column.Title = "Sync";
            select_column.PackStart (select_cell_renderer, false);
            select_column.AddAttribute (select_cell_renderer, "active", 0);

            //TODO enable checkbox in the selection window
            //playlist_tree.AppendColumn (select_column);
            // order of Append matters, so first add select, then the playlist
            playlist_tree.AppendColumn (playlist_column);

            // show all the widgets in this window
            ShowAll ();
        }
    }
}