~ubuntu-branches/debian/experimental/spyder/experimental

« back to all changes in this revision

Viewing changes to spyderlib/plugins/workingdirectory.py

  • Committer: Package Import Robot
  • Author(s): Picca Frédéric-Emmanuel
  • Date: 2013-02-27 09:51:28 UTC
  • mfrom: (1.1.18)
  • Revision ID: package-import@ubuntu.com-20130227095128-wtx1irpvf4vl79lj
Tags: 2.2.0~beta3+dfsg-1
* Imported Upstream version 2.2.0~beta3+dfsg
* debian /patches
  - 0002-feature-forwarded-add-icon-to-desktop-file.patch (deleted)
    this patch was integrated by the upstream.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# -*- coding: utf-8 -*-
2
 
#
3
 
# Copyright © 2009-2010 Pierre Raybaut
4
 
# Licensed under the terms of the MIT License
5
 
# (see spyderlib/__init__.py for details)
6
 
 
7
 
"""Working Directory Plugin"""
8
 
 
9
 
# pylint: disable=C0103
10
 
# pylint: disable=R0903
11
 
# pylint: disable=R0911
12
 
# pylint: disable=R0201
13
 
 
14
 
from spyderlib.qt.QtGui import (QToolBar, QLabel, QGroupBox, QVBoxLayout,
15
 
                                QHBoxLayout, QButtonGroup)
16
 
from spyderlib.qt.QtCore import SIGNAL, Signal
17
 
from spyderlib.qt.compat import getexistingdirectory
18
 
 
19
 
import os
20
 
import os.path as osp
21
 
 
22
 
# Local imports
23
 
from spyderlib.utils import encoding
24
 
from spyderlib.baseconfig import get_conf_path, _
25
 
from spyderlib.guiconfig import get_icon
26
 
from spyderlib.utils.qthelpers import get_std_icon, create_action
27
 
 
28
 
# Package local imports
29
 
from spyderlib.widgets.comboboxes import PathComboBox
30
 
from spyderlib.plugins import SpyderPluginMixin, PluginConfigPage
31
 
 
32
 
 
33
 
class WorkingDirectoryConfigPage(PluginConfigPage):
34
 
    def setup_page(self):
35
 
        about_label = QLabel(_("The <b>global working directory</b> is "
36
 
                    "the working directory for newly opened <i>consoles</i> "
37
 
                    "(Python/IPython interpreters and terminals), for the "
38
 
                    "<i>file explorer</i>, for the <i>find in files</i> "
39
 
                    "plugin and for new files created in the <i>editor</i>."))
40
 
        about_label.setWordWrap(True)
41
 
        
42
 
        startup_group = QGroupBox(_("Startup"))
43
 
        startup_bg = QButtonGroup(startup_group)
44
 
        startup_label = QLabel(_("At startup, the global working "
45
 
                                       "directory is:"))
46
 
        startup_label.setWordWrap(True)
47
 
        lastdir_radio = self.create_radiobutton(
48
 
                                _("the same as in last session"),
49
 
                                'startup/use_last_directory', True,
50
 
                                _("At startup, Spyder will restore the "
51
 
                                        "global directory from last session"),
52
 
                                button_group=startup_bg)
53
 
        thisdir_radio = self.create_radiobutton(
54
 
                                _("the following directory:"),
55
 
                                'startup/use_fixed_directory', False,
56
 
                                _("At startup, the global working "
57
 
                                        "directory will be the specified path"),
58
 
                                button_group=startup_bg)
59
 
        thisdir_bd = self.create_browsedir("", 'startup/fixed_directory',
60
 
                                           os.getcwdu())
61
 
        self.connect(thisdir_radio, SIGNAL("toggled(bool)"),
62
 
                     thisdir_bd.setEnabled)
63
 
        self.connect(lastdir_radio, SIGNAL("toggled(bool)"),
64
 
                     thisdir_bd.setDisabled)
65
 
        thisdir_layout = QHBoxLayout()
66
 
        thisdir_layout.addWidget(thisdir_radio)
67
 
        thisdir_layout.addWidget(thisdir_bd)
68
 
 
69
 
        editor_o_group = QGroupBox(_("Open file"))
70
 
        editor_o_label = QLabel(_("Files are opened from:"))
71
 
        editor_o_label.setWordWrap(True)
72
 
        editor_o_bg = QButtonGroup(editor_o_group)
73
 
        editor_o_radio1 = self.create_radiobutton(
74
 
                                _("the current file directory"),
75
 
                                'editor/open/browse_scriptdir', True,
76
 
                                button_group=editor_o_bg)
77
 
        editor_o_radio2 = self.create_radiobutton(
78
 
                                _("the global working directory"),
79
 
                                'editor/open/browse_workdir', False,
80
 
                                button_group=editor_o_bg)
81
 
        
82
 
        editor_n_group = QGroupBox(_("New file"))
83
 
        editor_n_label = QLabel(_("Files are created in:"))
84
 
        editor_n_label.setWordWrap(True)
85
 
        editor_n_bg = QButtonGroup(editor_n_group)
86
 
        editor_n_radio1 = self.create_radiobutton(
87
 
                                _("the current file directory"),
88
 
                                'editor/new/browse_scriptdir', False,
89
 
                                button_group=editor_n_bg)
90
 
        editor_n_radio2 = self.create_radiobutton(
91
 
                                _("the global working directory"),
92
 
                                'editor/new/browse_workdir', True,
93
 
                                button_group=editor_n_bg)
94
 
        # Note: default values for the options above are set in plugin's
95
 
        #       constructor (see below)
96
 
        
97
 
        other_group = QGroupBox(_("Change to file base directory"))
98
 
        newcb = self.create_checkbox
99
 
        open_box = newcb(_("When opening a file"),
100
 
                         'editor/open/auto_set_to_basedir', False)
101
 
        save_box = newcb(_("When saving a file"),
102
 
                         'editor/save/auto_set_to_basedir', False)
103
 
        
104
 
        startup_layout = QVBoxLayout()
105
 
        startup_layout.addWidget(startup_label)
106
 
        startup_layout.addWidget(lastdir_radio)
107
 
        startup_layout.addLayout(thisdir_layout)
108
 
        startup_group.setLayout(startup_layout)
109
 
 
110
 
        editor_o_layout = QVBoxLayout()
111
 
        editor_o_layout.addWidget(editor_o_label)
112
 
        editor_o_layout.addWidget(editor_o_radio1)
113
 
        editor_o_layout.addWidget(editor_o_radio2)
114
 
        editor_o_group.setLayout(editor_o_layout)
115
 
 
116
 
        editor_n_layout = QVBoxLayout()
117
 
        editor_n_layout.addWidget(editor_n_label)
118
 
        editor_n_layout.addWidget(editor_n_radio1)
119
 
        editor_n_layout.addWidget(editor_n_radio2)
120
 
        editor_n_group.setLayout(editor_n_layout)
121
 
        
122
 
        other_layout = QVBoxLayout()
123
 
        other_layout.addWidget(open_box)
124
 
        other_layout.addWidget(save_box)
125
 
        other_group.setLayout(other_layout)
126
 
        
127
 
        vlayout = QVBoxLayout()
128
 
        vlayout.addWidget(about_label)
129
 
        vlayout.addSpacing(10)
130
 
        vlayout.addWidget(startup_group)
131
 
        vlayout.addWidget(editor_o_group)
132
 
        vlayout.addWidget(editor_n_group)
133
 
        vlayout.addWidget(other_group)
134
 
        vlayout.addStretch(1)
135
 
        self.setLayout(vlayout)
136
 
 
137
 
 
138
 
class WorkingDirectory(QToolBar, SpyderPluginMixin):
139
 
    """
140
 
    Working directory changer widget
141
 
    """
142
 
    CONF_SECTION = 'workingdir'
143
 
    CONFIGWIDGET_CLASS = WorkingDirectoryConfigPage
144
 
    LOG_PATH = get_conf_path('.workingdir')
145
 
    sig_option_changed = Signal(str, object)
146
 
    def __init__(self, parent, workdir=None):
147
 
        QToolBar.__init__(self, parent)
148
 
        SpyderPluginMixin.__init__(self, parent)
149
 
 
150
 
        # Initialize plugin
151
 
        self.initialize_plugin()
152
 
        
153
 
        # Setting default values for editor-related options
154
 
        self.get_option('editor/open/browse_scriptdir', True)
155
 
        self.get_option('editor/open/browse_workdir', False)
156
 
        self.get_option('editor/new/browse_scriptdir', False)
157
 
        self.get_option('editor/new/browse_workdir', True)
158
 
        self.get_option('editor/open/auto_set_to_basedir', False)
159
 
        self.get_option('editor/save/auto_set_to_basedir', False)
160
 
        
161
 
        self.setWindowTitle(self.get_plugin_title()) # Toolbar title
162
 
        self.setObjectName(self.get_plugin_title()) # Used to save Window state
163
 
        
164
 
        # Previous dir action
165
 
        self.history = []
166
 
        self.histindex = None
167
 
        self.previous_action = create_action(self, "previous", None,
168
 
                                     get_icon('previous.png'), _('Back'),
169
 
                                     triggered=self.previous_directory)
170
 
        self.addAction(self.previous_action)
171
 
        
172
 
        # Next dir action
173
 
        self.history = []
174
 
        self.histindex = None
175
 
        self.next_action = create_action(self, "next", None,
176
 
                                     get_icon('next.png'), _('Next'),
177
 
                                     triggered=self.next_directory)
178
 
        self.addAction(self.next_action)
179
 
        
180
 
        # Enable/disable previous/next actions
181
 
        self.connect(self, SIGNAL("set_previous_enabled(bool)"),
182
 
                     self.previous_action.setEnabled)
183
 
        self.connect(self, SIGNAL("set_next_enabled(bool)"),
184
 
                     self.next_action.setEnabled)
185
 
        
186
 
        # Path combo box
187
 
        adjust = self.get_option('working_dir_adjusttocontents', False)
188
 
        self.pathedit = PathComboBox(self, adjust_to_contents=adjust)
189
 
        self.pathedit.setToolTip(_("This is the working directory for newly\n"
190
 
                               "opened consoles (Python interpreters and\n"
191
 
                               "terminals), for the file explorer, for the\n"
192
 
                               "find in files plugin and for new files\n"
193
 
                               "created in the editor"))
194
 
        self.connect(self.pathedit, SIGNAL("open_dir(QString)"), self.chdir)
195
 
        self.pathedit.setMaxCount(self.get_option('working_dir_history', 20))
196
 
        wdhistory = self.load_wdhistory( workdir )
197
 
        if workdir is None:
198
 
            if self.get_option('startup/use_last_directory', True):
199
 
                if wdhistory:
200
 
                    workdir = wdhistory[0]
201
 
                else:
202
 
                    workdir = "."
203
 
            else:
204
 
                workdir = self.get_option('startup/fixed_directory', ".")
205
 
                if not osp.isdir(workdir):
206
 
                    workdir = "."
207
 
        self.chdir(workdir)
208
 
        self.pathedit.addItems( wdhistory )
209
 
        self.refresh_plugin()
210
 
        self.addWidget(self.pathedit)
211
 
        
212
 
        # Browse action
213
 
        browse_action = create_action(self, "browse", None,
214
 
                                      get_std_icon('DirOpenIcon'),
215
 
                                      _('Browse a working directory'),
216
 
                                      triggered=self.select_directory)
217
 
        self.addAction(browse_action)
218
 
        
219
 
        # Set current console working directory action
220
 
        setwd_action = create_action(self, icon=get_icon('set_workdir.png'),
221
 
                                     text=_("Set as current console's "
222
 
                                                  "working directory"),
223
 
                                     triggered=self.set_as_current_console_wd)
224
 
        self.addAction(setwd_action)
225
 
        
226
 
        # Parent dir action
227
 
        parent_action = create_action(self, "parent", None,
228
 
                                      get_icon('up.png'),
229
 
                                      _('Change to parent directory'),
230
 
                                      triggered=self.parent_directory)
231
 
        self.addAction(parent_action)
232
 
                
233
 
    #------ SpyderPluginWidget API ---------------------------------------------    
234
 
    def get_plugin_title(self):
235
 
        """Return widget title"""
236
 
        return _('Global working directory')
237
 
    
238
 
    def get_plugin_icon(self):
239
 
        """Return widget icon"""
240
 
        return get_std_icon('DirOpenIcon')
241
 
        
242
 
    def get_plugin_actions(self):
243
 
        """Setup actions"""
244
 
        return (None, None)
245
 
    
246
 
    def register_plugin(self):
247
 
        """Register plugin in Spyder's main window"""
248
 
        self.connect(self, SIGNAL('redirect_stdio(bool)'),
249
 
                     self.main.redirect_internalshell_stdio)
250
 
        self.connect(self.main.console.shell, SIGNAL("refresh()"),
251
 
                     self.refresh_plugin)
252
 
        self.main.addToolBar(self)
253
 
        
254
 
    def refresh_plugin(self):
255
 
        """Refresh widget"""
256
 
        curdir = os.getcwdu()
257
 
        self.pathedit.add_text(curdir)
258
 
        self.save_wdhistory()
259
 
        self.emit(SIGNAL("set_previous_enabled(bool)"),
260
 
                  self.histindex is not None and self.histindex > 0)
261
 
        self.emit(SIGNAL("set_next_enabled(bool)"),
262
 
                  self.histindex is not None and \
263
 
                  self.histindex < len(self.history)-1)
264
 
 
265
 
    def apply_plugin_settings(self, options):
266
 
        """Apply configuration file's plugin settings"""
267
 
        pass
268
 
        
269
 
    def closing_plugin(self, cancelable=False):
270
 
        """Perform actions before parent main window is closed"""
271
 
        return True
272
 
        
273
 
    #------ Public API ---------------------------------------------------------
274
 
    def load_wdhistory(self, workdir=None):
275
 
        """Load history from a text file in user home directory"""
276
 
        if osp.isfile(self.LOG_PATH):
277
 
            wdhistory, _ = encoding.readlines(self.LOG_PATH)
278
 
            wdhistory = [name for name in wdhistory if os.path.isdir(name)]
279
 
        else:
280
 
            if workdir is None:
281
 
                workdir = os.getcwdu()
282
 
            wdhistory = [ workdir ]
283
 
        return wdhistory
284
 
    
285
 
    def save_wdhistory(self):
286
 
        """Save history to a text file in user home directory"""
287
 
        text = [ unicode( self.pathedit.itemText(index) ) \
288
 
                 for index in range(self.pathedit.count()) ]
289
 
        encoding.writelines(text, self.LOG_PATH)
290
 
        
291
 
    def select_directory(self):
292
 
        """Select directory"""
293
 
        self.emit(SIGNAL('redirect_stdio(bool)'), False)
294
 
        directory = getexistingdirectory(self.main, _("Select directory"),
295
 
                                         os.getcwdu())
296
 
        if directory:
297
 
            self.chdir(directory)
298
 
        self.emit(SIGNAL('redirect_stdio(bool)'), True)
299
 
        
300
 
    def previous_directory(self):
301
 
        """Back to previous directory"""
302
 
        self.histindex -= 1
303
 
        self.chdir(browsing_history=True)
304
 
        
305
 
    def next_directory(self):
306
 
        """Return to next directory"""
307
 
        self.histindex += 1
308
 
        self.chdir(browsing_history=True)
309
 
        
310
 
    def parent_directory(self):
311
 
        """Change working directory to parent directory"""
312
 
        self.chdir(os.path.join(os.getcwdu(), os.path.pardir))
313
 
        
314
 
    def chdir(self, directory=None, browsing_history=False,
315
 
              refresh_explorer=True):
316
 
        """Set directory as working directory"""
317
 
        # Working directory history management
318
 
        if directory is not None:
319
 
            directory = osp.abspath(unicode(directory))
320
 
        if browsing_history:
321
 
            directory = self.history[self.histindex]
322
 
        elif directory in self.history:
323
 
            self.histindex = self.history.index(directory)
324
 
        else:
325
 
            if self.histindex is None:
326
 
                self.history = []
327
 
            else:
328
 
                self.history = self.history[:self.histindex+1]
329
 
            self.history.append(directory)
330
 
            self.histindex = len(self.history)-1
331
 
        
332
 
        # Changing working directory
333
 
        os.chdir( unicode(directory) )
334
 
        self.refresh_plugin()
335
 
        if refresh_explorer:
336
 
            self.emit(SIGNAL("set_explorer_cwd(QString)"), directory)
337
 
        self.emit(SIGNAL("refresh_findinfiles()"))
338
 
        
339
 
    def set_as_current_console_wd(self):
340
 
        """Set as current console working directory"""
341
 
        self.emit(SIGNAL("set_current_console_wd(QString)"), os.getcwdu())
 
1
# -*- coding: utf-8 -*-
 
2
#
 
3
# Copyright © 2009-2010 Pierre Raybaut
 
4
# Licensed under the terms of the MIT License
 
5
# (see spyderlib/__init__.py for details)
 
6
 
 
7
"""Working Directory Plugin"""
 
8
 
 
9
# pylint: disable=C0103
 
10
# pylint: disable=R0903
 
11
# pylint: disable=R0911
 
12
# pylint: disable=R0201
 
13
 
 
14
from spyderlib.qt.QtGui import (QToolBar, QLabel, QGroupBox, QVBoxLayout,
 
15
                                QHBoxLayout, QButtonGroup)
 
16
from spyderlib.qt.QtCore import SIGNAL, Signal
 
17
from spyderlib.qt.compat import getexistingdirectory
 
18
 
 
19
import os
 
20
import os.path as osp
 
21
 
 
22
# Local imports
 
23
from spyderlib.utils import encoding
 
24
from spyderlib.baseconfig import get_conf_path, _
 
25
from spyderlib.utils.qthelpers import get_icon, get_std_icon, create_action
 
26
 
 
27
# Package local imports
 
28
from spyderlib.widgets.comboboxes import PathComboBox
 
29
from spyderlib.plugins import SpyderPluginMixin, PluginConfigPage
 
30
 
 
31
 
 
32
class WorkingDirectoryConfigPage(PluginConfigPage):
 
33
    def setup_page(self):
 
34
        about_label = QLabel(_("The <b>global working directory</b> is "
 
35
                    "the working directory for newly opened <i>consoles</i> "
 
36
                    "(Python/IPython interpreters and terminals), for the "
 
37
                    "<i>file explorer</i>, for the <i>find in files</i> "
 
38
                    "plugin and for new files created in the <i>editor</i>."))
 
39
        about_label.setWordWrap(True)
 
40
        
 
41
        startup_group = QGroupBox(_("Startup"))
 
42
        startup_bg = QButtonGroup(startup_group)
 
43
        startup_label = QLabel(_("At startup, the global working "
 
44
                                       "directory is:"))
 
45
        startup_label.setWordWrap(True)
 
46
        lastdir_radio = self.create_radiobutton(
 
47
                                _("the same as in last session"),
 
48
                                'startup/use_last_directory', True,
 
49
                                _("At startup, Spyder will restore the "
 
50
                                        "global directory from last session"),
 
51
                                button_group=startup_bg)
 
52
        thisdir_radio = self.create_radiobutton(
 
53
                                _("the following directory:"),
 
54
                                'startup/use_fixed_directory', False,
 
55
                                _("At startup, the global working "
 
56
                                        "directory will be the specified path"),
 
57
                                button_group=startup_bg)
 
58
        thisdir_bd = self.create_browsedir("", 'startup/fixed_directory',
 
59
                                           os.getcwdu())
 
60
        self.connect(thisdir_radio, SIGNAL("toggled(bool)"),
 
61
                     thisdir_bd.setEnabled)
 
62
        self.connect(lastdir_radio, SIGNAL("toggled(bool)"),
 
63
                     thisdir_bd.setDisabled)
 
64
        thisdir_layout = QHBoxLayout()
 
65
        thisdir_layout.addWidget(thisdir_radio)
 
66
        thisdir_layout.addWidget(thisdir_bd)
 
67
 
 
68
        editor_o_group = QGroupBox(_("Open file"))
 
69
        editor_o_label = QLabel(_("Files are opened from:"))
 
70
        editor_o_label.setWordWrap(True)
 
71
        editor_o_bg = QButtonGroup(editor_o_group)
 
72
        editor_o_radio1 = self.create_radiobutton(
 
73
                                _("the current file directory"),
 
74
                                'editor/open/browse_scriptdir', True,
 
75
                                button_group=editor_o_bg)
 
76
        editor_o_radio2 = self.create_radiobutton(
 
77
                                _("the global working directory"),
 
78
                                'editor/open/browse_workdir', False,
 
79
                                button_group=editor_o_bg)
 
80
        
 
81
        editor_n_group = QGroupBox(_("New file"))
 
82
        editor_n_label = QLabel(_("Files are created in:"))
 
83
        editor_n_label.setWordWrap(True)
 
84
        editor_n_bg = QButtonGroup(editor_n_group)
 
85
        editor_n_radio1 = self.create_radiobutton(
 
86
                                _("the current file directory"),
 
87
                                'editor/new/browse_scriptdir', False,
 
88
                                button_group=editor_n_bg)
 
89
        editor_n_radio2 = self.create_radiobutton(
 
90
                                _("the global working directory"),
 
91
                                'editor/new/browse_workdir', True,
 
92
                                button_group=editor_n_bg)
 
93
        # Note: default values for the options above are set in plugin's
 
94
        #       constructor (see below)
 
95
        
 
96
        other_group = QGroupBox(_("Change to file base directory"))
 
97
        newcb = self.create_checkbox
 
98
        open_box = newcb(_("When opening a file"),
 
99
                         'editor/open/auto_set_to_basedir', False)
 
100
        save_box = newcb(_("When saving a file"),
 
101
                         'editor/save/auto_set_to_basedir', False)
 
102
        
 
103
        startup_layout = QVBoxLayout()
 
104
        startup_layout.addWidget(startup_label)
 
105
        startup_layout.addWidget(lastdir_radio)
 
106
        startup_layout.addLayout(thisdir_layout)
 
107
        startup_group.setLayout(startup_layout)
 
108
 
 
109
        editor_o_layout = QVBoxLayout()
 
110
        editor_o_layout.addWidget(editor_o_label)
 
111
        editor_o_layout.addWidget(editor_o_radio1)
 
112
        editor_o_layout.addWidget(editor_o_radio2)
 
113
        editor_o_group.setLayout(editor_o_layout)
 
114
 
 
115
        editor_n_layout = QVBoxLayout()
 
116
        editor_n_layout.addWidget(editor_n_label)
 
117
        editor_n_layout.addWidget(editor_n_radio1)
 
118
        editor_n_layout.addWidget(editor_n_radio2)
 
119
        editor_n_group.setLayout(editor_n_layout)
 
120
        
 
121
        other_layout = QVBoxLayout()
 
122
        other_layout.addWidget(open_box)
 
123
        other_layout.addWidget(save_box)
 
124
        other_group.setLayout(other_layout)
 
125
        
 
126
        vlayout = QVBoxLayout()
 
127
        vlayout.addWidget(about_label)
 
128
        vlayout.addSpacing(10)
 
129
        vlayout.addWidget(startup_group)
 
130
        vlayout.addWidget(editor_o_group)
 
131
        vlayout.addWidget(editor_n_group)
 
132
        vlayout.addWidget(other_group)
 
133
        vlayout.addStretch(1)
 
134
        self.setLayout(vlayout)
 
135
 
 
136
 
 
137
class WorkingDirectory(QToolBar, SpyderPluginMixin):
 
138
    """
 
139
    Working directory changer widget
 
140
    """
 
141
    CONF_SECTION = 'workingdir'
 
142
    CONFIGWIDGET_CLASS = WorkingDirectoryConfigPage
 
143
    LOG_PATH = get_conf_path('.workingdir')
 
144
    sig_option_changed = Signal(str, object)
 
145
    def __init__(self, parent, workdir=None):
 
146
        QToolBar.__init__(self, parent)
 
147
        SpyderPluginMixin.__init__(self, parent)
 
148
 
 
149
        # Initialize plugin
 
150
        self.initialize_plugin()
 
151
        
 
152
        # Setting default values for editor-related options
 
153
        self.get_option('editor/open/browse_scriptdir', True)
 
154
        self.get_option('editor/open/browse_workdir', False)
 
155
        self.get_option('editor/new/browse_scriptdir', False)
 
156
        self.get_option('editor/new/browse_workdir', True)
 
157
        self.get_option('editor/open/auto_set_to_basedir', False)
 
158
        self.get_option('editor/save/auto_set_to_basedir', False)
 
159
        
 
160
        self.setWindowTitle(self.get_plugin_title()) # Toolbar title
 
161
        self.setObjectName(self.get_plugin_title()) # Used to save Window state
 
162
        
 
163
        # Previous dir action
 
164
        self.history = []
 
165
        self.histindex = None
 
166
        self.previous_action = create_action(self, "previous", None,
 
167
                                     get_icon('previous.png'), _('Back'),
 
168
                                     triggered=self.previous_directory)
 
169
        self.addAction(self.previous_action)
 
170
        
 
171
        # Next dir action
 
172
        self.history = []
 
173
        self.histindex = None
 
174
        self.next_action = create_action(self, "next", None,
 
175
                                     get_icon('next.png'), _('Next'),
 
176
                                     triggered=self.next_directory)
 
177
        self.addAction(self.next_action)
 
178
        
 
179
        # Enable/disable previous/next actions
 
180
        self.connect(self, SIGNAL("set_previous_enabled(bool)"),
 
181
                     self.previous_action.setEnabled)
 
182
        self.connect(self, SIGNAL("set_next_enabled(bool)"),
 
183
                     self.next_action.setEnabled)
 
184
        
 
185
        # Path combo box
 
186
        adjust = self.get_option('working_dir_adjusttocontents', False)
 
187
        self.pathedit = PathComboBox(self, adjust_to_contents=adjust)
 
188
        self.pathedit.setToolTip(_("This is the working directory for newly\n"
 
189
                               "opened consoles (Python interpreters and\n"
 
190
                               "terminals), for the file explorer, for the\n"
 
191
                               "find in files plugin and for new files\n"
 
192
                               "created in the editor"))
 
193
        self.connect(self.pathedit, SIGNAL("open_dir(QString)"), self.chdir)
 
194
        self.pathedit.setMaxCount(self.get_option('working_dir_history', 20))
 
195
        wdhistory = self.load_wdhistory( workdir )
 
196
        if workdir is None:
 
197
            if self.get_option('startup/use_last_directory', True):
 
198
                if wdhistory:
 
199
                    workdir = wdhistory[0]
 
200
                else:
 
201
                    workdir = "."
 
202
            else:
 
203
                workdir = self.get_option('startup/fixed_directory', ".")
 
204
                if not osp.isdir(workdir):
 
205
                    workdir = "."
 
206
        self.chdir(workdir)
 
207
        self.pathedit.addItems( wdhistory )
 
208
        self.refresh_plugin()
 
209
        self.addWidget(self.pathedit)
 
210
        
 
211
        # Browse action
 
212
        browse_action = create_action(self, "browse", None,
 
213
                                      get_std_icon('DirOpenIcon'),
 
214
                                      _('Browse a working directory'),
 
215
                                      triggered=self.select_directory)
 
216
        self.addAction(browse_action)
 
217
        
 
218
        # Set current console working directory action
 
219
        setwd_action = create_action(self, icon=get_icon('set_workdir.png'),
 
220
                                     text=_("Set as current console's "
 
221
                                                  "working directory"),
 
222
                                     triggered=self.set_as_current_console_wd)
 
223
        self.addAction(setwd_action)
 
224
        
 
225
        # Parent dir action
 
226
        parent_action = create_action(self, "parent", None,
 
227
                                      get_icon('up.png'),
 
228
                                      _('Change to parent directory'),
 
229
                                      triggered=self.parent_directory)
 
230
        self.addAction(parent_action)
 
231
                
 
232
    #------ SpyderPluginWidget API ---------------------------------------------    
 
233
    def get_plugin_title(self):
 
234
        """Return widget title"""
 
235
        return _('Global working directory')
 
236
    
 
237
    def get_plugin_icon(self):
 
238
        """Return widget icon"""
 
239
        return get_std_icon('DirOpenIcon')
 
240
        
 
241
    def get_plugin_actions(self):
 
242
        """Setup actions"""
 
243
        return (None, None)
 
244
    
 
245
    def register_plugin(self):
 
246
        """Register plugin in Spyder's main window"""
 
247
        self.connect(self, SIGNAL('redirect_stdio(bool)'),
 
248
                     self.main.redirect_internalshell_stdio)
 
249
        self.connect(self.main.console.shell, SIGNAL("refresh()"),
 
250
                     self.refresh_plugin)
 
251
        self.main.addToolBar(self)
 
252
        
 
253
    def refresh_plugin(self):
 
254
        """Refresh widget"""
 
255
        curdir = os.getcwdu()
 
256
        self.pathedit.add_text(curdir)
 
257
        self.save_wdhistory()
 
258
        self.emit(SIGNAL("set_previous_enabled(bool)"),
 
259
                  self.histindex is not None and self.histindex > 0)
 
260
        self.emit(SIGNAL("set_next_enabled(bool)"),
 
261
                  self.histindex is not None and \
 
262
                  self.histindex < len(self.history)-1)
 
263
 
 
264
    def apply_plugin_settings(self, options):
 
265
        """Apply configuration file's plugin settings"""
 
266
        pass
 
267
        
 
268
    def closing_plugin(self, cancelable=False):
 
269
        """Perform actions before parent main window is closed"""
 
270
        return True
 
271
        
 
272
    #------ Public API ---------------------------------------------------------
 
273
    def load_wdhistory(self, workdir=None):
 
274
        """Load history from a text file in user home directory"""
 
275
        if osp.isfile(self.LOG_PATH):
 
276
            wdhistory, _ = encoding.readlines(self.LOG_PATH)
 
277
            wdhistory = [name for name in wdhistory if os.path.isdir(name)]
 
278
        else:
 
279
            if workdir is None:
 
280
                workdir = os.getcwdu()
 
281
            wdhistory = [ workdir ]
 
282
        return wdhistory
 
283
    
 
284
    def save_wdhistory(self):
 
285
        """Save history to a text file in user home directory"""
 
286
        text = [ unicode( self.pathedit.itemText(index) ) \
 
287
                 for index in range(self.pathedit.count()) ]
 
288
        encoding.writelines(text, self.LOG_PATH)
 
289
        
 
290
    def select_directory(self):
 
291
        """Select directory"""
 
292
        self.emit(SIGNAL('redirect_stdio(bool)'), False)
 
293
        directory = getexistingdirectory(self.main, _("Select directory"),
 
294
                                         os.getcwdu())
 
295
        if directory:
 
296
            self.chdir(directory)
 
297
        self.emit(SIGNAL('redirect_stdio(bool)'), True)
 
298
        
 
299
    def previous_directory(self):
 
300
        """Back to previous directory"""
 
301
        self.histindex -= 1
 
302
        self.chdir(browsing_history=True)
 
303
        
 
304
    def next_directory(self):
 
305
        """Return to next directory"""
 
306
        self.histindex += 1
 
307
        self.chdir(browsing_history=True)
 
308
        
 
309
    def parent_directory(self):
 
310
        """Change working directory to parent directory"""
 
311
        self.chdir(os.path.join(os.getcwdu(), os.path.pardir))
 
312
        
 
313
    def chdir(self, directory=None, browsing_history=False,
 
314
              refresh_explorer=True):
 
315
        """Set directory as working directory"""
 
316
        # Working directory history management
 
317
        if directory is not None:
 
318
            directory = osp.abspath(unicode(directory))
 
319
        if browsing_history:
 
320
            directory = self.history[self.histindex]
 
321
        elif directory in self.history:
 
322
            self.histindex = self.history.index(directory)
 
323
        else:
 
324
            if self.histindex is None:
 
325
                self.history = []
 
326
            else:
 
327
                self.history = self.history[:self.histindex+1]
 
328
            self.history.append(directory)
 
329
            self.histindex = len(self.history)-1
 
330
        
 
331
        # Changing working directory
 
332
        os.chdir( unicode(directory) )
 
333
        self.refresh_plugin()
 
334
        if refresh_explorer:
 
335
            self.emit(SIGNAL("set_explorer_cwd(QString)"), directory)
 
336
        self.emit(SIGNAL("refresh_findinfiles()"))
 
337
        
 
338
    def set_as_current_console_wd(self):
 
339
        """Set as current console working directory"""
 
340
        self.emit(SIGNAL("set_current_console_wd(QString)"), os.getcwdu())