Skip to content
This repository was archived by the owner on Aug 28, 2020. It is now read-only.

Commit 28eb68c

Browse files
committed
Merge pull request #119 from robertbasic/feature/projects
Feature/projects. Resolves #101
2 parents 10af7ae + 5529017 commit 28eb68c

File tree

7 files changed

+492
-96
lines changed

7 files changed

+492
-96
lines changed

pugdebug/gui/forms.py

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
# -*- coding: utf-8 -*-
2+
3+
"""
4+
pugdebug - a standalone PHP debugger
5+
=========================
6+
copyright: (c) 2015 Robert Basic
7+
license: GNU GPL v3, see LICENSE for more details
8+
"""
9+
10+
__author__ = "robertbasic"
11+
12+
from PyQt5.QtWidgets import (QLineEdit, QFormLayout, QSpinBox, QCheckBox,
13+
QGroupBox)
14+
15+
16+
class PugdebugSettingsForm():
17+
18+
def __init__(self):
19+
# Construct the widgets
20+
self.widgets = {
21+
'path/project_root': QLineEdit(),
22+
'path/path_mapping': QLineEdit(),
23+
'debugger/host': QLineEdit(),
24+
'debugger/port_number': QSpinBox(),
25+
'debugger/idekey': QLineEdit(),
26+
'debugger/break_at_first_line': QCheckBox("Break at first line"),
27+
'debugger/max_depth': QLineEdit(),
28+
'debugger/max_children': QLineEdit(),
29+
'debugger/max_data': QLineEdit(),
30+
}
31+
32+
# Widget settings
33+
self.widgets['debugger/port_number'].setRange(1, 65535)
34+
35+
self.setup_path_widgets()
36+
self.setup_debugger_widgets()
37+
38+
def setup_path_widgets(self):
39+
path_layout = QFormLayout()
40+
path_layout.addRow("Root:", self.widgets['path/project_root'])
41+
path_layout.addRow("Maps from:", self.widgets['path/path_mapping'])
42+
43+
self.path_group = QGroupBox("Path")
44+
self.path_group.setLayout(path_layout)
45+
46+
def setup_debugger_widgets(self):
47+
debugger_layout = QFormLayout()
48+
debugger_layout.addRow("Host", self.widgets['debugger/host'])
49+
debugger_layout.addRow("Port", self.widgets['debugger/port_number'])
50+
debugger_layout.addRow("IDE Key", self.widgets['debugger/idekey'])
51+
debugger_layout.addRow(
52+
"",
53+
self.widgets['debugger/break_at_first_line']
54+
)
55+
debugger_layout.addRow("Max depth", self.widgets['debugger/max_depth'])
56+
debugger_layout.addRow(
57+
"Max children",
58+
self.widgets['debugger/max_children']
59+
)
60+
debugger_layout.addRow("Max data", self.widgets['debugger/max_data'])
61+
62+
self.debugger_group = QGroupBox("Debugger")
63+
self.debugger_group.setLayout(debugger_layout)
64+
65+
def set_widget_value(self, widget, value):
66+
"""A generic method which can set the value of any of the used widgets.
67+
"""
68+
if isinstance(widget, QLineEdit):
69+
widget.setText(value)
70+
elif isinstance(widget, QSpinBox):
71+
widget.setValue(int(value))
72+
elif isinstance(widget, QCheckBox):
73+
widget.setCheckState(int(value))
74+
else:
75+
name = type(widget).__name__
76+
raise Exception("Don't know how to set a value for %s" % name)
77+
78+
def get_widget_value(self, widget):
79+
"""A generic method which can set the value of any of the used widgets.
80+
"""
81+
if isinstance(widget, QLineEdit):
82+
return widget.text()
83+
elif isinstance(widget, QSpinBox):
84+
return widget.value()
85+
elif isinstance(widget, QCheckBox):
86+
return widget.checkState()
87+
else:
88+
name = type(widget).__name__
89+
raise Exception("Don't know how to get a value for %s" % name)

pugdebug/gui/main_window.py

Lines changed: 42 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,15 @@
99

1010
__author__ = "robertbasic"
1111

12-
from PyQt5.QtCore import Qt
12+
from PyQt5.QtCore import Qt, pyqtSignal
1313
from PyQt5.QtWidgets import (QMainWindow, QToolBar, QMenuBar, QDockWidget,
1414
QAction)
1515
from PyQt5.QtGui import QFont, QKeySequence
1616

1717
from pugdebug.gui.file_browser import PugdebugFileBrowser
1818
from pugdebug.gui.settings import PugdebugSettingsWindow
19+
from pugdebug.gui.projects import (PugdebugNewProjectWindow,
20+
PugdebugProjectsBrowser)
1921
from pugdebug.gui.documents import PugdebugDocumentViewer
2022
from pugdebug.gui.variables import PugdebugVariableViewer
2123
from pugdebug.gui.stacktraces import PugdebugStacktraceViewer
@@ -27,6 +29,8 @@
2729

2830
class PugdebugMainWindow(QMainWindow):
2931

32+
new_project_created_signal = pyqtSignal(str)
33+
3034
def __init__(self):
3135
super(PugdebugMainWindow, self).__init__()
3236
self.setObjectName("pugdebug")
@@ -36,7 +40,9 @@ def __init__(self):
3640
self.restoreGeometry(get_setting("window/geometry"))
3741

3842
self.file_browser = PugdebugFileBrowser()
43+
self.projects_browser = PugdebugProjectsBrowser()
3944
self.settings_window = PugdebugSettingsWindow(self)
45+
self.new_project_window = PugdebugNewProjectWindow(self)
4046
self.document_viewer = PugdebugDocumentViewer()
4147
self.variable_viewer = PugdebugVariableViewer()
4248
self.breakpoint_viewer = PugdebugBreakpointViewer()
@@ -60,6 +66,8 @@ def setup_gui_elements(self):
6066
self.setup_fonts()
6167
self.setup_docks()
6268

69+
self.setup_file_actions()
70+
6371
self.setup_actions()
6472
self.toggle_actions(False)
6573

@@ -85,6 +93,12 @@ def setup_docks(self):
8593
Qt.LeftDockWidgetArea
8694
)
8795

96+
self.__add_dock_widget(
97+
self.projects_browser,
98+
"Projects Browser",
99+
Qt.LeftDockWidgetArea
100+
)
101+
88102
self.__add_dock_widget(
89103
self.variable_viewer,
90104
"Variables",
@@ -109,6 +123,29 @@ def setup_docks(self):
109123
Qt.BottomDockWidgetArea
110124
)
111125

126+
def setup_file_actions(self):
127+
self.new_project_action = QAction("&New project", self)
128+
self.new_project_action.setToolTip("Create a new project (Ctrl+N)")
129+
self.new_project_action.setStatusTip(
130+
"Create a new project. Shortcut: Ctrl+N"
131+
)
132+
self.new_project_action.setShortcut(QKeySequence("Ctrl+N"))
133+
self.new_project_action.triggered.connect(self.new_project_window.exec)
134+
135+
self.show_settings_action = QAction("&Settings", self)
136+
self.show_settings_action.setToolTip("Show settings (Ctrl+S)")
137+
self.show_settings_action.setStatusTip(
138+
"Show the settings window. Shortcut: Ctrl+S"
139+
)
140+
self.show_settings_action.setShortcut(QKeySequence("Ctrl+S"))
141+
self.show_settings_action.triggered.connect(self.settings_window.exec)
142+
143+
self.quit_action = QAction("&Quit", self)
144+
self.quit_action.setToolTip("Exit the application (Alt+F4)")
145+
self.quit_action.setStatusTip("Exit the application. Shortcut: Alt+F4")
146+
self.quit_action.setShortcut(QKeySequence("Alt+F4"))
147+
self.quit_action.triggered.connect(self.close)
148+
112149
def setup_actions(self):
113150
self.start_debug_action = QAction("Start", self)
114151
self.start_debug_action.setToolTip("Start server (F1)")
@@ -167,17 +204,6 @@ def setup_actions(self):
167204
)
168205
self.step_out_action.setShortcut(QKeySequence("F8"))
169206

170-
self.show_settings_action = QAction("&Settings", self)
171-
self.show_settings_action.setToolTip("Show settings")
172-
self.show_settings_action.setStatusTip("Show the settings window.")
173-
self.show_settings_action.triggered.connect(self.settings_window.exec)
174-
175-
self.quit_action = QAction("&Quit", self)
176-
self.quit_action.setToolTip("Exit the application (Alt+F4)")
177-
self.quit_action.setStatusTip("Exit the application. Shortcut: Alt+F4")
178-
self.quit_action.setShortcut(QKeySequence("Alt+F4"))
179-
self.quit_action.triggered.connect(self.close)
180-
181207
def setup_toolbar(self):
182208
toolbar = QToolBar("Main Toolbar")
183209
toolbar.setObjectName("main-toolbar")
@@ -197,6 +223,7 @@ def setup_menubar(self):
197223
menu_bar = QMenuBar()
198224

199225
file_menu = menu_bar.addMenu("&File")
226+
file_menu.addAction(self.new_project_action)
200227
file_menu.addAction(self.show_settings_action)
201228
file_menu.addSeparator()
202229
file_menu.addAction(self.quit_action)
@@ -231,6 +258,9 @@ def toggle_actions(self, enabled):
231258
def get_file_browser(self):
232259
return self.file_browser
233260

261+
def get_projects_browser(self):
262+
return self.projects_browser
263+
234264
def get_settings(self):
235265
return self.settings_window
236266

pugdebug/gui/projects.py

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
# -*- coding: utf-8 -*-
2+
3+
"""
4+
pugdebug - a standalone PHP debugger
5+
=========================
6+
copyright: (c) 2015 Robert Basic
7+
license: GNU GPL v3, see LICENSE for more details
8+
"""
9+
10+
__author__ = "robertbasic"
11+
12+
from PyQt5.QtCore import Qt
13+
from PyQt5.QtWidgets import (QDialog, QPushButton, QVBoxLayout, QHBoxLayout,
14+
QFormLayout, QLineEdit, QTreeView, QAction, QMenu)
15+
from PyQt5.QtGui import QIcon
16+
17+
from pugdebug.gui.forms import PugdebugSettingsForm
18+
from pugdebug.models.projects import PugdebugProject
19+
from pugdebug.models.settings import get_default_setting, add_project
20+
21+
22+
class PugdebugNewProjectWindow(QDialog):
23+
24+
def __init__(self, parent):
25+
super(PugdebugNewProjectWindow, self).__init__(parent)
26+
27+
self.parent = parent
28+
29+
self.form = PugdebugSettingsForm()
30+
31+
self.project_name = QLineEdit()
32+
33+
self.accepted.connect(self.create_new_project)
34+
35+
self.setup_layout()
36+
37+
self.load_settings()
38+
39+
def setup_layout(self):
40+
project_name_layout = QFormLayout()
41+
project_name_layout.addRow("Project name:", self.project_name)
42+
43+
# Buttons
44+
save_button = QPushButton("&Save")
45+
save_button.clicked.connect(self.accept)
46+
47+
cancel_button = QPushButton("&Cancel")
48+
cancel_button.clicked.connect(self.reject)
49+
50+
button_layout = QHBoxLayout()
51+
button_layout.addWidget(cancel_button)
52+
button_layout.addWidget(save_button)
53+
54+
box_layout = QVBoxLayout()
55+
box_layout.addLayout(project_name_layout)
56+
box_layout.addWidget(self.form.path_group)
57+
box_layout.addWidget(self.form.debugger_group)
58+
box_layout.addLayout(button_layout)
59+
60+
self.setLayout(box_layout)
61+
62+
def create_new_project(self):
63+
project_name = self.project_name.text()
64+
project = PugdebugProject(project_name)
65+
66+
for name, widget in self.form.widgets.items():
67+
value = self.form.get_widget_value(widget)
68+
project.setValue(name, value)
69+
70+
project_name = project.get_project_name()
71+
72+
add_project(project_name)
73+
74+
self.parent.new_project_created_signal.emit(project_name)
75+
76+
def load_settings(self):
77+
"""Load default settings into the form"""
78+
for name, widget in self.form.widgets.items():
79+
value = get_default_setting(name)
80+
self.form.set_widget_value(widget, value)
81+
82+
83+
class PugdebugProjectsBrowser(QTreeView):
84+
85+
def __init__(self):
86+
super(PugdebugProjectsBrowser, self).__init__()
87+
88+
self.delete_action = QAction(
89+
QIcon.fromTheme('list-remove'),
90+
"&Delete",
91+
self
92+
)
93+
self.delete_action.triggered.connect(self.handle_delete_action)
94+
95+
self.setContextMenuPolicy(Qt.CustomContextMenu)
96+
self.customContextMenuRequested.connect(self.show_context_menu)
97+
98+
def load_projects(self):
99+
model = self.model()
100+
model.load_projects()
101+
102+
def show_context_menu(self, point):
103+
context_menu = QMenu(self)
104+
105+
if self.indexAt(point):
106+
context_menu.addAction(self.delete_action)
107+
108+
point = self.mapToGlobal(point)
109+
context_menu.popup(point)
110+
111+
def handle_delete_action(self):
112+
for index in self.selectedIndexes():
113+
project = self.model().get_project_by_index(index)
114+
project.delete()
115+
116+
self.load_projects()

0 commit comments

Comments
 (0)