-
Notifications
You must be signed in to change notification settings - Fork 0
/
Anubis.py
400 lines (317 loc) · 11 KB
/
Anubis.py
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
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
############# author => Anubis Graduation Team ############
############# this project is part of my graduation project and it intends to make a fully functioned IDE from scratch ########
############# I've borrowed a function (serial_ports()) from a guy in stack overflow whome I can't remember his name, so I gave hime the copyrights of this function, thank you ########
import os
import sys
import glob
import serial
import Python_Coloring
from PyQt5 import QtCore
from PyQt5 import QtGui
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from pathlib import Path
def serial_ports():
""" Lists serial port names
:raises EnvironmentError:
On unsupported or unknown platforms
:returns:
A list of the serial ports available on the system
"""
if sys.platform.startswith('win'):
ports = ['COM%s' % (i + 1) for i in range(256)]
elif sys.platform.startswith('linux') or sys.platform.startswith('cygwin'):
# this excludes your current terminal "/dev/tty"
ports = glob.glob('/dev/tty[A-Za-z]*')
elif sys.platform.startswith('darwin'):
ports = glob.glob('/dev/tty.*')
else:
raise EnvironmentError('Unsupported platform')
result = []
for port in ports:
try:
s = serial.Serial(port)
s.close()
result.append(port)
except (OSError, serial.SerialException):
pass
return result
#
#
#
#
############ Signal Class ############
#
#
#
#
class Signal(QObject):
# initializing a Signal which will take (string) as an input
reading = pyqtSignal(str)
# init Function for the Signal class
def __init__(self):
QObject.__init__(self)
#
#
############ end of Class ############
#
#
# Making text editor as A global variable (to solve the issue of being local to (self) in widget class)
text = QTextEdit
text2 = QTextEdit
#
#
#
#
############ Text Widget Class ############
#
#
#
#
# this class is made to connect the QTab with the necessary layouts
class text_widget(QWidget):
def __init__(self):
super().__init__()
self.itUI()
def itUI(self):
global text
text = QTextEdit()
Python_Coloring.PythonHighlighter(text)
hbox = QHBoxLayout()
hbox.addWidget(text)
self.setLayout(hbox)
#
#
############ end of Class ############
#
#
#
#
#
#
############ Widget Class ############
#
#
#
#
class Widget(QWidget):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
# This widget is responsible of making Tab in IDE which makes the Text editor looks nice
tab = QTabWidget()
tx = text_widget()
tab.addTab(tx, "Tab" + "1")
# second editor in which the error messeges and succeeded connections will be shown
global text2
text2 = QTextEdit()
text2.setReadOnly(True)
# defining a Treeview variable to use it in showing the directory included files
self.treeview = QTreeView()
# making a variable (path) and setting it to the root path (surely I can set it to whatever the root I want, not the default)
# path = QDir.rootPath()
path = QDir.currentPath()
# making a Filesystem variable, setting its root path and applying somefilters (which I need) on it
self.dirModel = QFileSystemModel()
self.dirModel.setRootPath(QDir.rootPath())
# NoDotAndDotDot => Do not list the special entries "." and "..".
# AllDirs =>List all directories; i.e. don't apply the filters to directory names.
# Files => List files.
self.dirModel.setFilter(QDir.NoDotAndDotDot | QDir.AllDirs | QDir.Files)
self.treeview.setModel(self.dirModel)
self.treeview.setRootIndex(self.dirModel.index(path))
self.treeview.clicked.connect(self.on_clicked)
vbox = QVBoxLayout()
Left_hbox = QHBoxLayout()
Right_hbox = QHBoxLayout()
# after defining variables of type QVBox and QHBox
# I will Assign treevies variable to the left one and the first text editor in which the code will be written to the right one
Left_hbox.addWidget(self.treeview)
Right_hbox.addWidget(tab)
# defining another variable of type Qwidget to set its layout as an QHBoxLayout
# I will do the same with the right one
Left_hbox_Layout = QWidget()
Left_hbox_Layout.setLayout(Left_hbox)
Right_hbox_Layout = QWidget()
Right_hbox_Layout.setLayout(Right_hbox)
# I defined a splitter to seperate the two variables (left, right) and make it more easily to change the space between them
H_splitter = QSplitter(Qt.Horizontal)
H_splitter.addWidget(Left_hbox_Layout)
H_splitter.addWidget(Right_hbox_Layout)
H_splitter.setStretchFactor(1, 1)
# I defined a new splitter to seperate between the upper and lower sides of the window
V_splitter = QSplitter(Qt.Vertical)
V_splitter.addWidget(H_splitter)
V_splitter.addWidget(text2)
Final_Layout = QHBoxLayout(self)
Final_Layout.addWidget(V_splitter)
self.setLayout(Final_Layout)
# defining a new Slot (takes string) to save the text inside the first text editor
@pyqtSlot(str)
def Saving(s):
with open('SavedFile.py', 'w') as f:
TEXT = text.toPlainText()
f.write(TEXT)
# Save as C#
@pyqtSlot(str)
def SavingCS(s):
with open('SavedFile.cs', 'w') as f:
TEXT = text.toPlainText()
f.write(TEXT)
# defining a new Slot (takes string) to set the string to the text editor
@pyqtSlot(str)
def Open(s):
global text
text.setText(s)
def on_clicked(self, index):
nn = self.sender().model().filePath(index)
# Add the CS Extension
Python_Coloring.ext = os.path.splitext(nn)[1]
nn = tuple([nn])
if nn[0]:
f = open(nn[0], 'r')
with f:
data = f.read()
text.setText(data)
#
#
############ end of Class ############
#
#
# defining a new Slot (takes string)
# Actually I could connect the (mainwindow) class directly to the (widget class) but I've made this function in between for futuer use
# All what it do is to take the (input string) and establish a connection with the widget class, send the string to it
@pyqtSlot(str)
def reading(s):
b = Signal()
b.reading.connect(Widget.Saving)
b.reading.emit(s)
# Added function for saving as .cs
@pyqtSlot(str)
def ReadingCS(s):
b = Signal()
b.reading.connect(Widget.SavingCS)
b.reading.emit(s)
# same as reading Function
@pyqtSlot(str)
def Openning(s):
b = Signal()
b.reading.connect(Widget.Open)
b.reading.emit(s)
#
#
#
#
############ MainWindow Class ############
#
#
#
#
class UI(QMainWindow):
def __init__(self):
super().__init__()
self.intUI()
def intUI(self):
self.port_flag = 1
self.b = Signal()
self.Open_Signal = Signal()
# for the save as .cs functionality
self.SaveAsCS = Signal()
self.SaveAsCS.reading.connect(ReadingCS)
# connecting (self.Open_Signal) with Openning function
self.Open_Signal.reading.connect(Openning)
# connecting (self.b) with reading function
self.b.reading.connect(reading)
# creating menu items
menu = self.menuBar()
# I have three menu items
filemenu = menu.addMenu('File')
Port = menu.addMenu('Port')
Run = menu.addMenu('Run')
# As any PC or laptop have many ports, so I need to list them to the User
# so I made (Port_Action) to add the Ports got from (serial_ports()) function
# copyrights of serial_ports() function goes back to a guy from stackoverflow(whome I can't remember his name), so thank you (unknown)
Port_Action = QMenu('port', self)
res = serial_ports()
for i in range(len(res)):
s = res[i]
Port_Action.addAction(s, self.PortClicked)
# adding the menu which I made to the original (Port menu)
Port.addMenu(Port_Action)
# Port_Action.triggered.connect(self.Port)
# Port.addAction(Port_Action)
# Making and adding Run Actions
RunAction = QAction("Run", self)
RunAction.triggered.connect(self.Run)
Run.addAction(RunAction)
# Making and adding File Features
Save_Action = QAction("Save as .py", self)
Save_Action.triggered.connect(self.save)
Save_Action.setShortcut("Ctrl+S")
# __________________________________________#
# Added saving as .cs format
SaveActionCS = QAction("Save as .cs", self)
SaveActionCS.triggered.connect(self.SaveCS)
# ______________________________________________#
Close_Action = QAction("Close", self)
Close_Action.setShortcut("Alt+c")
Close_Action.triggered.connect(self.close)
Open_Action = QAction("Open", self)
Open_Action.setShortcut("Ctrl+O")
Open_Action.triggered.connect(self.open)
filemenu.addAction(Save_Action)
# Add Save as C# Action
filemenu.addAction(SaveActionCS)
filemenu.addAction(Close_Action)
filemenu.addAction(Open_Action)
# Seting the window Geometry
self.setGeometry(200, 150, 600, 500)
self.setWindowTitle('Anubis IDE')
self.setWindowIcon(QtGui.QIcon('Anubis.png'))
widget = Widget()
self.setCentralWidget(widget)
self.show()
########################### Start OF the Functions ##################
def Run(self):
if self.port_flag == 0:
mytext = text.toPlainText()
#
##### Compiler Part
#
# ide.create_file(mytext)
# ide.upload_file(self.portNo)
text2.append("Sorry, there is no attached compiler.")
else:
text2.append("Please Select Your Port Number First")
# this function is made to get which port was selected by the user
@QtCore.pyqtSlot()
def PortClicked(self):
action = self.sender()
self.portNo = action.text()
self.port_flag = 0
# I made this function to save the code into a file
def save(self):
self.b.reading.emit("name")
# Saving as CS Functionality
def SaveCS(self):
self.SaveAsCS.reading.emit("name")
# I made this function to open a file and exhibits it to the user in a text editor
def open(self):
file_name = QFileDialog.getOpenFileName(self, 'Open File', '/home')
if file_name[0]:
Python_Coloring.ext = os.path.splitext(file_name[0])[1]
f = open(file_name[0], 'r')
with f:
data = f.read()
self.Open_Signal.reading.emit(data)
#
#
############ end of Class ############
#
#
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = UI()
# ex = Widget()
sys.exit(app.exec_())