q2rad 0.1.201__py3-none-any.whl → 0.1.203__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of q2rad might be problematic. Click here for more details.

q2rad/q2actions.py CHANGED
@@ -18,6 +18,7 @@ from q2gui.q2model import Q2CursorModel
18
18
  from q2rad.q2raddb import last_error, insert
19
19
  from q2rad.q2utils import q2cursor, choice_form, choice_column, Q2_save_and_run, Q2Form, int_
20
20
  from q2gui import q2app
21
+
21
22
  # from q2rad import Q2Form
22
23
 
23
24
  import gettext
@@ -44,17 +45,9 @@ class Q2Actions(Q2Form, Q2_save_and_run):
44
45
  self.add_action("Copy to", icon="❖", worker=self.copy_to)
45
46
 
46
47
  def create_form(self):
48
+ from q2rad.q2forms import Q2Forms
49
+
47
50
  self.add_control("id", "", datatype="int", pk="*", ai="*", noform=1, nogrid=1)
48
- self.add_control(
49
- "name",
50
- _("Form"),
51
- disabled="*",
52
- to_table="forms",
53
- to_column="name",
54
- related="name",
55
- datatype="char",
56
- datalen=100,
57
- )
58
51
  self.add_control("action_text", _("Action text"), datatype="char", datalen=100)
59
52
  self.add_control("/")
60
53
  if self.add_control("/t", _("Main"), tag="tab"):
@@ -119,8 +112,22 @@ class Q2Actions(Q2Form, Q2_save_and_run):
119
112
  control="radio",
120
113
  datatype="int",
121
114
  )
115
+ self.add_control("/")
116
+ self.add_control("/f")
117
+ self.add_control(
118
+ "name",
119
+ _("Form"),
120
+ # disabled="*",
121
+ to_table="forms",
122
+ to_column="name",
123
+ to_form=Q2Forms(),
124
+ related="name",
125
+ datatype="char",
126
+ datalen=100,
127
+ )
122
128
 
123
129
  self.add_control("/s")
130
+
124
131
  self.add_control("/t", _("Action Script"))
125
132
  self.add_control(
126
133
  "action_worker",
@@ -151,7 +158,8 @@ class Q2Actions(Q2Form, Q2_save_and_run):
151
158
  seq = (
152
159
  int_(
153
160
  q2cursor(
154
- f"select max(seq) as maxseq from actions where name='{choice['name']}'", q2app.q2_app.db_logic
161
+ f"select max(seq) as maxseq from actions where name='{choice['name']}'",
162
+ q2app.q2_app.db_logic,
155
163
  ).r.maxseq
156
164
  )
157
165
  + 1
@@ -159,7 +167,7 @@ class Q2Actions(Q2Form, Q2_save_and_run):
159
167
  for x in rows:
160
168
  rec = self.model.get_record(x)
161
169
  rec["seq"] = seq
162
- rec["name"] = choice['name']
170
+ rec["name"] = choice["name"]
163
171
  seq += 1
164
172
  if not insert("actions", rec, q2app.q2_app.db_logic):
165
173
  print(last_error(q2app.q2_app.db_logic))
@@ -184,7 +192,7 @@ class Q2Actions(Q2Form, Q2_save_and_run):
184
192
  def select_child_form(self):
185
193
  choice = choice_form()
186
194
  if choice:
187
- self.s.child_form = choice['name']
195
+ self.s.child_form = choice["name"]
188
196
  if self.s.child_where == "":
189
197
  parent_pk = q2cursor(
190
198
  f"""select column
@@ -199,7 +207,7 @@ class Q2Actions(Q2Form, Q2_save_and_run):
199
207
  if self.s.child_where.startswith("=") or self.s.child_where == "":
200
208
  choice = choice_column(self.s.child_form)
201
209
  if choice:
202
- self.s.child_where = choice['col'] + self.s.child_where
210
+ self.s.child_where = choice["col"] + self.s.child_where
203
211
 
204
212
  def before_form_show(self):
205
213
  self.action_mode_valid()
q2rad/q2appmanager.py CHANGED
@@ -20,7 +20,7 @@ from q2gui.q2dialogs import q2AskYN, q2Mess, Q2WaitShow, q2ask, q2working
20
20
 
21
21
  from q2rad import Q2Form
22
22
  from q2terminal.q2terminal import Q2Terminal
23
- from q2rad.q2raddb import today, insert, update, get
23
+ from q2rad.q2raddb import insert, update, get
24
24
  from datetime import datetime
25
25
 
26
26
  import json
@@ -50,7 +50,6 @@ class AppManager(Q2Form):
50
50
  "upgrade",
51
51
  "Check updates",
52
52
  control="button",
53
- datalen=10,
54
53
  valid=q2app.q2_app.update_packages,
55
54
  )
56
55
 
@@ -76,7 +75,6 @@ class AppManager(Q2Form):
76
75
  "reload_assets",
77
76
  "Reload assets",
78
77
  control="button",
79
- datalen=10,
80
78
  valid=self.reload_assets,
81
79
  )
82
80
 
@@ -110,7 +108,7 @@ class AppManager(Q2Form):
110
108
  self.add_control(
111
109
  "drl",
112
110
  "Database type",
113
- data=app_data["driver_logic"],
111
+ data=app_data["driver_logic"].lower(),
114
112
  disabled=1,
115
113
  datalen=len(app_data["driver_logic"].strip()) + 5,
116
114
  )
@@ -188,7 +186,7 @@ class AppManager(Q2Form):
188
186
  self.add_control(
189
187
  "drd",
190
188
  "Database type",
191
- data=app_data["driver_data"],
189
+ data=app_data["driver_data"].lower(),
192
190
  disabled=1,
193
191
  datalen=len(app_data["driver_data"].strip()) + 5,
194
192
  )
q2rad/q2appselector.py CHANGED
@@ -15,8 +15,8 @@
15
15
 
16
16
  from q2gui import q2app
17
17
  from q2gui.q2form import NEW, COPY
18
- from q2gui.q2model import Q2CursorModel
19
- from q2gui.q2dialogs import q2Mess, q2Wait, q2mess, q2working
18
+ from q2gui.q2dialogs import q2Mess
19
+ from q2gui.q2utils import Q2Crypto
20
20
 
21
21
  from q2db.schema import Q2DbSchema
22
22
  from q2db.db import Q2Db
@@ -33,7 +33,7 @@ from q2rad.q2appmanager import AppManager
33
33
  from q2rad.q2raddb import open_url
34
34
 
35
35
 
36
- SQL_ENGINES = ["MySQl", "Sqlite", "Postgresql"]
36
+ SQL_ENGINES = ["MySQL", "SQLite", "PostgreSQL"]
37
37
 
38
38
  _ = gettext.gettext
39
39
 
@@ -81,11 +81,6 @@ class Q2AppSelect(Q2Form):
81
81
  self.add_control("/")
82
82
  if self.add_control("/f", _("Data storage")):
83
83
 
84
- def driverDataValid(self=self):
85
- self.w.host_data.set_enabled(self.s.driver_data != "Sqlite")
86
- self.w.port_data.set_enabled(self.s.driver_data != "Sqlite")
87
- self.w.select_data_storage_file.set_enabled(self.s.driver_data == "Sqlite")
88
-
89
84
  self.add_control(
90
85
  "driver_data",
91
86
  label=_("Storage type"),
@@ -94,7 +89,7 @@ class Q2AppSelect(Q2Form):
94
89
  datatype="char",
95
90
  datalen=30,
96
91
  pic=";".join(SQL_ENGINES),
97
- valid=driverDataValid,
92
+ valid=self.driver_data_valid,
98
93
  )
99
94
  if self.add_control("/h"):
100
95
  self.add_control(
@@ -109,7 +104,6 @@ class Q2AppSelect(Q2Form):
109
104
  _("?"),
110
105
  mess=_("Open Data Storage sqlite database file"),
111
106
  control="button",
112
- datalen=3,
113
107
  valid=self.openSqliteDataFile,
114
108
  )
115
109
  self.add_control("/")
@@ -130,11 +124,6 @@ class Q2AppSelect(Q2Form):
130
124
 
131
125
  if self.add_control("/f", _("Logic storage")):
132
126
 
133
- def driverLogicValid(form=self):
134
- form.w.host_logic.set_enabled(form.s.driver_logic != "Sqlite")
135
- form.w.port_logic.set_enabled(form.s.driver_logic != "Sqlite")
136
- form.w.select_app_storage_file.set_enabled(form.s.driver_logic == "Sqlite")
137
-
138
127
  self.add_control(
139
128
  "driver_logic",
140
129
  label=_("Storage type"),
@@ -143,7 +132,7 @@ class Q2AppSelect(Q2Form):
143
132
  datatype="char",
144
133
  datalen=30,
145
134
  pic=";".join(SQL_ENGINES),
146
- valid=driverLogicValid,
135
+ valid=self.driver_logic_valid,
147
136
  )
148
137
  if self.add_control("/h"):
149
138
  self.add_control(
@@ -158,7 +147,6 @@ class Q2AppSelect(Q2Form):
158
147
  _("?"),
159
148
  mess=_("Open App Storage sqlite database file"),
160
149
  control="button",
161
- datalen=3,
162
150
  valid=self.openSqliteDataFile,
163
151
  )
164
152
  self.add_control("/")
@@ -174,6 +162,19 @@ class Q2AppSelect(Q2Form):
174
162
  mess=_("Allow to change App"),
175
163
  )
176
164
  self.add_control("/")
165
+ self.add_control("/")
166
+
167
+ if self.add_control("/h", "Database Credentials"):
168
+ self.add_control("epwd", "Credentials settings", control="button", valid=self.show_password_form)
169
+ self.add_control(
170
+ "credhash",
171
+ "Credhash",
172
+ datatype="char",
173
+ datalen=256,
174
+ noform=1,
175
+ nogrid=1,
176
+ )
177
+ self.add_control("/")
177
178
 
178
179
  self.add_action(
179
180
  _("Select"),
@@ -202,6 +203,147 @@ class Q2AppSelect(Q2Form):
202
203
 
203
204
  self.actions.add_action("/crud")
204
205
 
206
+ @staticmethod
207
+ def decrypt_creds(pin, credhash):
208
+ creds = Q2Crypto(pin).decrypt(credhash)
209
+ if creds is not None:
210
+ username = creds.split(":")[0]
211
+ password = creds.split(":")[1]
212
+ return username, password
213
+ else:
214
+ return None
215
+
216
+ def show_password_form(self):
217
+ username = ""
218
+ password = ""
219
+ if self.crud_mode == "EDIT" and self.s.credhash:
220
+ pin = self.get_pin(self.r.name)
221
+ if pin is None:
222
+ return
223
+ if Q2Crypto(pin).check_pin(self.s.credhash) is None:
224
+ q2Mess("Wrong PIN")
225
+ return
226
+ creds = self.decrypt_creds(pin, self.s.credhash)
227
+ if creds is not None:
228
+ username, password = creds
229
+ else:
230
+ pin = ""
231
+
232
+ pform = Q2Form("Database credentials")
233
+ pform.add_control("/f", "Username")
234
+ pform.add_control(
235
+ "user1",
236
+ "Enter username",
237
+ datatype="char",
238
+ datalen=100,
239
+ pic="*",
240
+ data=username,
241
+ )
242
+ pform.add_control(
243
+ "user2",
244
+ "Repeat username",
245
+ datatype="char",
246
+ datalen=100,
247
+ pic="*",
248
+ data=username,
249
+ )
250
+ pform.add_control("/")
251
+
252
+ pform.add_control("/")
253
+ pform.add_control("/f", "Password")
254
+ pform.add_control(
255
+ "pass1",
256
+ "Enter password",
257
+ datatype="char",
258
+ datalen=100,
259
+ pic="*",
260
+ data=password,
261
+ )
262
+ pform.add_control(
263
+ "pass2",
264
+ "Repeat password",
265
+ datatype="char",
266
+ datalen=100,
267
+ pic="*",
268
+ data=password,
269
+ )
270
+ pform.add_control("/")
271
+ pform.add_control("/f", "Protect credentials with PIN")
272
+ pform.add_control("pin1", "Enter PIN", datatype="char", datalen=10, pic="*", data=pin)
273
+ pform.add_control("pin2", "Repeat PIN", datatype="char", datalen=10, pic="*", data=pin)
274
+ pform.add_control("/")
275
+
276
+ def after_form_show():
277
+ pass
278
+
279
+ pform.after_form_show = after_form_show
280
+
281
+ def valid():
282
+ if (pform.s.user1 or pform.s.user2) and pform.s.user1 != pform.s.user2:
283
+ q2Mess("Username mismatch")
284
+ return False
285
+ if (pform.s.pass1 or pform.s.pass2) and pform.s.pass1 != pform.s.pass2:
286
+ q2Mess("Password mismatch")
287
+ return False
288
+ if (pform.s.pin1 or pform.s.pin2) and pform.s.pin1 != pform.s.pin2:
289
+ q2Mess("PIN mismatch")
290
+ return False
291
+ return True
292
+
293
+ pform.valid = valid
294
+ pform.ok_button = 1
295
+ pform.cancel_button = 1
296
+ pform.run()
297
+
298
+ if pform.ok_pressed:
299
+ if pform.s.user1 == "" and pform.s.pass1 == "":
300
+ self.s.credhash = ""
301
+ else:
302
+ self.s.credhash = Q2Crypto(pform.s.pin1).encrypt(pform.s.user1 + ":" + pform.s.pass1)
303
+
304
+ def get_pin(self, app_name=""):
305
+ pinform = Q2Form("Enter PIN")
306
+ pinform.add_control("/")
307
+ pinform.add_control("/h")
308
+ pinform.add_control("/s")
309
+ pinform.add_control("", "Application:", control="label")
310
+ pinform.add_control("appname", app_name, control="label", style="color:green;font-weight:bold;background:white")
311
+ pinform.add_control("/s")
312
+ pinform.add_control("/")
313
+ pinform.add_control("/f")
314
+ pinform.add_control("pin", "PIN", pic="*")
315
+ pinform.ok_button = 1
316
+ pinform.cancel_button = 1
317
+
318
+ # def before_form_show():
319
+ # pinform.w.appname.set_style_sheet("color:green;font-weight:bold")
320
+
321
+ # pinform.before_form_show = before_form_show
322
+ pinform.run()
323
+ if pinform.ok_pressed:
324
+ return pinform.s.pin
325
+ else:
326
+ return None
327
+
328
+ def driver_logic_valid(self):
329
+ is_sqlite = self.s.driver_logic.lower() == "sqlite"
330
+ self.w.host_logic.set_enabled(not is_sqlite)
331
+ self.w.port_logic.set_enabled(not is_sqlite)
332
+ self.w.select_app_storage_file.set_enabled(is_sqlite)
333
+ self.credentials_fields_enable()
334
+
335
+ def driver_data_valid(self):
336
+ is_sqlite = self.s.driver_data.lower() == "sqlite"
337
+ self.w.host_data.set_enabled(not is_sqlite)
338
+ self.w.port_data.set_enabled(not is_sqlite)
339
+ self.w.select_data_storage_file.set_enabled(is_sqlite)
340
+ self.credentials_fields_enable()
341
+
342
+ def credentials_fields_enable(self):
343
+ creds_required = self.s.driver_data.lower() != "sqlite" or self.s.driver_logic.lower() != "sqlite"
344
+ # self.w.credhash.set_enabled(creds_required)
345
+ self.w.epwd.set_enabled(creds_required)
346
+
205
347
  def set_autoload(self):
206
348
  clean_this = self.r.autoselect
207
349
  self.db.cursor("update applications set autoselect='' ")
@@ -223,9 +365,6 @@ class Q2AppSelect(Q2Form):
223
365
  self.s.database_data = fname
224
366
 
225
367
  def before_grid_show(self):
226
- self.q2_app.sleep(0.2)
227
- if self.q2_app.keyboard_modifiers() != "":
228
- return
229
368
  if self.db.table("applications").row_count() <= 0:
230
369
  if not os.path.isdir("databases"):
231
370
  os.mkdir("databases")
@@ -234,15 +373,22 @@ class Q2AppSelect(Q2Form):
234
373
  {
235
374
  "ordnum": 1,
236
375
  "name": "My first app",
237
- "driver_data": "Sqlite",
376
+ "driver_data": "SQLite",
238
377
  "database_data": "databases/my_first_app_data_storage.sqlite",
239
- "driver_logic": "Sqlite",
378
+ "driver_logic": "SQLite",
240
379
  "database_logic": "databases/my_first_app_logic_storage.sqlite",
241
380
  "dev_mode": "",
242
381
  },
243
382
  self.db,
244
383
  )
245
384
  self.refresh()
385
+ elif (
386
+ q2cursor("select * from applications where autoselect<>''", self.db).row_count() == 1
387
+ ): # seek autoload
388
+ for row in range(self.model.row_count()):
389
+ if self.model.get_record(row).get("autoselect"):
390
+ self.set_grid_index(row)
391
+ break
246
392
 
247
393
  def before_crud_save(self):
248
394
  if self.s.name == "":
@@ -258,13 +404,13 @@ class Q2AppSelect(Q2Form):
258
404
  self.w.database_logic.set_focus()
259
405
  return False
260
406
 
261
- if self.s.driver_logic == "Sqlite":
407
+ if self.s.driver_logic.lower() == "sqlite":
262
408
  self.s.host_logic = ""
263
409
  self.s.port_logic = ""
264
410
  if not os.path.isdir(os.path.dirname(self.s.database_logic)):
265
411
  os.makedirs(os.path.dirname(self.s.database_logic))
266
412
 
267
- if self.s.driver_data == "Sqlite":
413
+ if self.s.driver_data.lower() == "sqlite":
268
414
  self.s.host_data = ""
269
415
  self.s.port_data = ""
270
416
  if not os.path.isdir(os.path.dirname(self.s.database_data)):
@@ -276,11 +422,19 @@ class Q2AppSelect(Q2Form):
276
422
 
277
423
  def before_form_show(self):
278
424
  if self.crud_mode == "NEW":
279
- self.s.driver_logic = "Sqlite"
280
- self.s.driver_data = "Sqlite"
425
+ self.s.driver_logic = "SQLite"
426
+ self.s.driver_data = "SQLite"
281
427
  self.s.dev_mode = ""
282
428
  self.s.database_logic = "databases/_logic"
283
429
  self.s.database_data = "databases/_data"
430
+ else:
431
+ self.s.driver_logic = SQL_ENGINES[
432
+ ["mysql", "sqlite", "postgresql"].index(self.r.driver_logic.lower())
433
+ ]
434
+ self.s.driver_data = SQL_ENGINES[
435
+ ["mysql", "sqlite", "postgresql"].index(self.r.driver_data.lower())
436
+ ]
437
+
284
438
  self.w.driver_data.valid()
285
439
  self.w.driver_logic.valid()
286
440
  if self.crud_mode in [NEW, COPY]:
@@ -289,9 +443,9 @@ class Q2AppSelect(Q2Form):
289
443
 
290
444
  def run_demo(self):
291
445
  row = {
292
- "driver_data": "Sqlite",
446
+ "driver_data": "SQLite",
293
447
  "database_data": ":memory:",
294
- "driver_logic": "Sqlite",
448
+ "driver_logic": "SQLite",
295
449
  "database_logic": ":memory:",
296
450
  "dev_mode": "",
297
451
  }
@@ -313,6 +467,19 @@ class Q2AppSelect(Q2Form):
313
467
  q2Mess(_("Can't to load Demo App"))
314
468
 
315
469
  def _select_application(self, app_data={}):
470
+ if app_data.get("credhash"):
471
+ pin = self.get_pin(app_data.get("name", ""))
472
+ if pin is None:
473
+ return False
474
+ creds = self.decrypt_creds(pin, app_data.get("credhash"))
475
+ if creds is None:
476
+ q2Mess("Wrong PIN")
477
+ return False
478
+ app_data["username"] = creds[0]
479
+ app_data["password"] = creds[1]
480
+ else:
481
+ app_data["username"] = "q2user"
482
+ app_data["password"] = "q2password"
316
483
  q2_app: Q2App = q2app.q2_app
317
484
  q2_app.dev_mode = app_data.get("dev_mode")
318
485
  q2_app.selected_application = app_data
@@ -322,11 +489,13 @@ class Q2AppSelect(Q2Form):
322
489
  q2_app.show_statusbar()
323
490
  q2_app.show_tabbar()
324
491
  self.q2_app.process_events()
492
+ return True
325
493
 
326
494
  def select_application(self):
327
- self.close()
495
+ # self.close()
328
496
  self.q2_app.process_events()
329
- self._select_application(self.model.get_record(self.current_row))
497
+ if self._select_application(self.model.get_record(self.current_row)):
498
+ self.close()
330
499
 
331
500
  def run(self, autoload_enabled=True):
332
501
  q2_app: Q2App = q2app.q2_app
@@ -338,9 +507,12 @@ class Q2AppSelect(Q2Form):
338
507
  q2_app.hide_tabbar()
339
508
 
340
509
  self.autoload_enabled = autoload_enabled
341
- if autoload_enabled:
510
+ self.q2_app.process_events()
511
+ self.q2_app.sleep(0.1)
512
+ km = self.q2_app.keyboard_modifiers()
513
+ if autoload_enabled and km != "shift":
342
514
  cu = q2cursor("select * from applications where autoselect<>''", self.db)
343
515
  if cu.row_count() > 0:
344
- self._select_application(cu.record(0))
345
- return False
516
+ if self._select_application(cu.record(0)):
517
+ return False
346
518
  super().run()
q2rad/q2lines.py CHANGED
@@ -102,17 +102,8 @@ class Q2Lines(Q2Form, Q2_save_and_run):
102
102
  self.add_action("Alter column", icon="🔧", worker=self.alter_column)
103
103
 
104
104
  def create_form(self):
105
+ from q2rad.q2forms import Q2Forms
105
106
  self.add_control("id", "", datatype="int", pk="*", ai="*", noform=1, nogrid=1)
106
- self.add_control(
107
- "name",
108
- _("Form"),
109
- # disabled="*",
110
- to_table="forms",
111
- to_column="name",
112
- related="name",
113
- datatype="char",
114
- datalen=100,
115
- )
116
107
  self.add_control("column", _("Column name"), datalen=50)
117
108
  self.add_control("/")
118
109
  if self.add_control("/t", _("Main")):
@@ -197,7 +188,6 @@ class Q2Lines(Q2Form, Q2_save_and_run):
197
188
  _("?"),
198
189
  mess=_("Open list of existing tables"),
199
190
  control="button",
200
- datalen=3,
201
191
  valid=self.select_linked_table,
202
192
  )
203
193
  self.add_control("to_table", gridlabel=_("To table"), datatype="char", datalen=100)
@@ -208,20 +198,20 @@ class Q2Lines(Q2Form, Q2_save_and_run):
208
198
  _("?"),
209
199
  mess=_("Open list of existing tables"),
210
200
  control="button",
211
- datalen=3,
212
201
  valid=self.select_linked_table_pk,
213
202
  )
214
203
  self.add_control("to_column", gridlabel=_("To field"), datatype="char", datalen=100)
215
204
  self.add_control("/")
216
205
  if self.add_control("/h", _("Data to show")):
206
+ self.add_control("/v")
217
207
  self.add_control(
218
208
  "select_column",
219
209
  _("?"),
220
210
  mess=_("Open list of existing columns"),
221
211
  control="button",
222
- datalen=3,
223
212
  valid=self.select_linked_table_column,
224
213
  )
214
+ self.add_control("/")
225
215
  self.add_control(
226
216
  "related", control="codesql", gridlabel=_("Data to show"), datatype="text"
227
217
  )
@@ -232,7 +222,6 @@ class Q2Lines(Q2Form, Q2_save_and_run):
232
222
  _("?"),
233
223
  mess=_("Open list of existing forms"),
234
224
  control="button",
235
- datalen=3,
236
225
  valid=self.select_linked_form,
237
226
  )
238
227
  self.add_control("to_form", gridlabel=_("Form to open"), datatype="char", datalen=100)
@@ -240,6 +229,20 @@ class Q2Lines(Q2Form, Q2_save_and_run):
240
229
 
241
230
  self.add_control("/")
242
231
 
232
+ self.add_control("/f")
233
+ self.add_control(
234
+ "name",
235
+ _("Form"),
236
+ # disabled="*",
237
+ to_table="forms",
238
+ to_column="name",
239
+ to_form=Q2Forms(),
240
+ related="name",
241
+ datatype="char",
242
+ datalen=100,
243
+ )
244
+ self.add_control("/")
245
+
243
246
  self.add_control("/s")
244
247
 
245
248
  self.add_control("/t", _("Comment"))
@@ -268,6 +271,13 @@ class Q2Lines(Q2Form, Q2_save_and_run):
268
271
  nogrid="*",
269
272
  datatype="longtext",
270
273
  )
274
+ self.add_control("/t", _("Stylesheet"))
275
+ self.add_control(
276
+ "style",
277
+ control="code",
278
+ nogrid="*",
279
+ datatype="longtext",
280
+ )
271
281
  self.add_control("/")
272
282
  self._add_save_and_run()
273
283
  self._add_save_and_run_visible()
q2rad/q2queries.py CHANGED
@@ -171,6 +171,7 @@ class Q2QueryEdit(Q2Form):
171
171
  self.query_list = Q2QueryList(self)
172
172
  self.param_list = Q2ParamList()
173
173
  self.actions = Q2Actions()
174
+ self._db = None
174
175
  self.actions.add_action("Run F4", self.query_list.sql_runner, hotkey="F4")
175
176
 
176
177
  self.actions.show_main_button = 0
@@ -257,7 +258,7 @@ class Q2QueryList(Q2Form):
257
258
  sql = sql.replace(x, f"{value}")
258
259
  else:
259
260
  sql = sql.replace(x, f"'{value}'")
260
- q2cursor(sql).browse()
261
+ q2cursor(sql, q2_db=self.query_editor_form._db).browse()
261
262
 
262
263
  def sql_to_model(self, sql):
263
264
  self.model.update({"sql": sql}, self.current_row, refresh=False)
@@ -317,7 +318,6 @@ class Q2ParamList(Q2Form):
317
318
  return params
318
319
 
319
320
  def get_param(self, param):
320
- print(self.model.records)
321
321
  for x in self.model.records:
322
322
  if x["name"] == (param[1:] if param.startswith(":") else param[1:-1]):
323
323
  return x["value"]
q2rad/q2rad.py CHANGED
@@ -297,9 +297,9 @@ class Q2RadApp(Q2App):
297
297
  self.open_selected_app(True)
298
298
  self.check_app_update()
299
299
  self.on_new_tab()
300
- # self.update_app_packages()
301
300
  else:
302
301
  self.close()
302
+ self.subwindow_count_changed()
303
303
 
304
304
  def open_selected_app(self, go_to_q2market=False):
305
305
  wait = Q2WaitShow(5, "Loading app> ")
@@ -475,8 +475,8 @@ class Q2RadApp(Q2App):
475
475
  host=self.selected_application.get("host_data", ""),
476
476
  port=self.selected_application.get("port_data", ""),
477
477
  guest_mode=self.selected_application.get("guest_mode", ""),
478
- user="q2user",
479
- password="q2password",
478
+ user=self.selected_application.get("username", ""),
479
+ password=self.selected_application.get("password", ""),
480
480
  )
481
481
  self.db = self.db_data
482
482
  if self.db_data:
@@ -485,8 +485,8 @@ class Q2RadApp(Q2App):
485
485
  db_engine_name=self.selected_application.get("driver_logic", "").lower(),
486
486
  host=self.selected_application.get("host_logic", ""),
487
487
  port=self.selected_application.get("port_logic", ""),
488
- user="q2user",
489
- password="q2password",
488
+ user=self.selected_application.get("username", ""),
489
+ password=self.selected_application.get("password", ""),
490
490
  )
491
491
  self.last_root_password = ""
492
492
  if self.db_data is None or self.db_logic is None:
@@ -1040,6 +1040,7 @@ class Q2RadApp(Q2App):
1040
1040
  , code_valid as valid
1041
1041
  , code_when as _when
1042
1042
  , code_show as _show
1043
+ , style
1043
1044
  from `lines`
1044
1045
  where name = '{name}'
1045
1046
  order by seq
q2rad/q2stylesettings.py CHANGED
@@ -114,8 +114,8 @@ class AppStyleSettings(Q2Form):
114
114
  self.q2_app.set_color_mode(color_mode)
115
115
 
116
116
  def font_size_valid(self):
117
- if int_(self.s.font_size) < 8:
118
- self.s.font_size = 8
117
+ if int_(self.s.font_size) < 10:
118
+ self.s.font_size = 10
119
119
  if self.s.apply:
120
120
  self.q2_app.q2style.font_size = int_(self.s.font_size)
121
121
  self.style_valid()
q2rad/q2utils.py CHANGED
@@ -81,6 +81,7 @@ class Q2Form(_Q2Form):
81
81
  tag="",
82
82
  eat_enter=None,
83
83
  hotkey="",
84
+ style="",
84
85
  **args,
85
86
  ):
86
87
  if isinstance(to_form, str) and to_form != "":
@@ -123,6 +124,7 @@ class Q2Form(_Q2Form):
123
124
  tag,
124
125
  eat_enter,
125
126
  hotkey,
127
+ style,
126
128
  **args,
127
129
  )
128
130
 
@@ -217,7 +219,8 @@ class Q2Form(_Q2Form):
217
219
  f"""select *
218
220
  from log_{self.model.get_table_name()}
219
221
  where {pk} = '{self.r.__getattr__(pk)}'
220
- """
222
+ """,
223
+ q2_db=self.db,
221
224
  )
222
225
  elif choice == 3:
223
226
  where = self.model.get_where()
@@ -264,6 +267,7 @@ class Q2Form(_Q2Form):
264
267
  from q2rad.q2queries import Q2QueryEdit
265
268
 
266
269
  form.query_edit = Q2QueryEdit()
270
+ form.query_edit._db = self.db
267
271
  form.add_control("ql", "", widget=form.query_edit, nogrid=1, migrate=0)
268
272
 
269
273
  def after_form_show():
q2rad/version.py CHANGED
@@ -1 +1 @@
1
- __version__ = "0.1.201"
1
+ __version__ = "0.1.203"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: q2rad
3
- Version: 0.1.201
3
+ Version: 0.1.203
4
4
  Summary: RAD - database, GUI, reports
5
5
  Author: Andrei Puchko
6
6
  Author-email: andrei.puchko@gmx.de
@@ -0,0 +1,24 @@
1
+ q2rad/__init__.py,sha256=Y0Up-UTXOmCYC9llNmTF10CpDDgF2kv10pyHT3-YwmQ,183
2
+ q2rad/__main__.py,sha256=zP4JARM-FzFHM-vWLehx7c5N4v4m_F-TuMobCdFzr4Q,824
3
+ q2rad/q2actions.py,sha256=eExRvOSyLhT_v1XCR-DmLEhQ9g_LRkrlyXnwDCjT0LM,8258
4
+ q2rad/q2appmanager.py,sha256=pdEdyTXWr9zjdZgVmfNXJrjDmQ_Ntq21udhD1b4vA2I,15975
5
+ q2rad/q2appselector.py,sha256=PZWSXaiUswinB_Zj1Q8fyRhzqK9ViB8lUHlNVUr85rI,18597
6
+ q2rad/q2constants.py,sha256=dQtN4OMvZw0FATDAFYjolI7eGMVUnNnbTl6qM-ggZ4I,3416
7
+ q2rad/q2forms.py,sha256=A5VeBK8OdE3zn0L1TgvCk4OjpB1nLibJqBFfpVZr_Uc,10181
8
+ q2rad/q2lines.py,sha256=yHQAEULVt9FTSgZa3atnoTSBSXMHCEMCjAK08ARhNMc,17167
9
+ q2rad/q2make.py,sha256=wXoyBUwf2zaAl9JjWDCbjAteUElRq0O7ippyaMY9eug,6476
10
+ q2rad/q2market.py,sha256=nyIBhZYqxNSlBXpcxdBRQ1vGSzWV8jI4cQoVa9JdRhE,2589
11
+ q2rad/q2modules.py,sha256=N3OkUKfiwVZtmDyAtnJcs2Rprd7uIHd0HhjHTyFoN_s,4294
12
+ q2rad/q2packages.py,sha256=ifRu8LuVrrTphiJe1JUVED_KB2sHJCPVnZq9VEh3K8w,3473
13
+ q2rad/q2queries.py,sha256=EXcau1UCdPrvTvsYr0857NoXldmrkhdrkmbUTk5LrMQ,12536
14
+ q2rad/q2rad.py,sha256=IYQQaTGRagUTWTuhS8Jy8ua2ERCuTlBaCKC4DRP9pDY,46031
15
+ q2rad/q2raddb.py,sha256=ISqT5EBFO7eaXcQRNpA0hMiRU84kbd-FcfckwKMlGfs,4506
16
+ q2rad/q2reports.py,sha256=Q-bZONOSDDQPrLziHTpW_L6FS82CkWzxITkv5EX5x98,84439
17
+ q2rad/q2stylesettings.py,sha256=rEJLyLzsffJEXnMbg9bPB3KHLjYfw-49QgrtcYOfGV0,4769
18
+ q2rad/q2utils.py,sha256=tLiDYgGGUCUwDRpyxirIc3xe0hPquzXhYvJw6bL-8jI,19219
19
+ q2rad/version.py,sha256=ibT5FfNRP69rFPNhBV9hZ1u7zlfZmf4fSwvzMRzfu_o,23
20
+ q2rad-0.1.203.dist-info/entry_points.txt,sha256=DmsJQE6f3wYuhdN2h6ARYxSe8_d03paeepfGpdVj5rs,42
21
+ q2rad-0.1.203.dist-info/LICENSE,sha256=JRR3LlR18ghhYXT4G2cWgXmnxRvcuVcKlqncWWK4MRY,10347
22
+ q2rad-0.1.203.dist-info/METADATA,sha256=1JfnGyY7aSvHk4kupptJBiIJtGIZwoco4ps6rV1AMxo,3369
23
+ q2rad-0.1.203.dist-info/WHEEL,sha256=WGfLGfLX43Ei_YORXSnT54hxFygu34kMpcQdmgmEwCQ,88
24
+ q2rad-0.1.203.dist-info/RECORD,,
@@ -1,24 +0,0 @@
1
- q2rad/__init__.py,sha256=Y0Up-UTXOmCYC9llNmTF10CpDDgF2kv10pyHT3-YwmQ,183
2
- q2rad/__main__.py,sha256=zP4JARM-FzFHM-vWLehx7c5N4v4m_F-TuMobCdFzr4Q,824
3
- q2rad/q2actions.py,sha256=Xqrpm68e36KVzyrmbDP8wDJfh-C_PVS-YTCF5nAQdcU,8034
4
- q2rad/q2appmanager.py,sha256=FFty5-BvXou21kHabnBzetgKIpHL2JiYBsDtQrn_9cw,16028
5
- q2rad/q2appselector.py,sha256=3VlYG2kn0cOVOuRfA3dWIStvtnyKZWmfbP9Jpb8w9VI,12595
6
- q2rad/q2constants.py,sha256=dQtN4OMvZw0FATDAFYjolI7eGMVUnNnbTl6qM-ggZ4I,3416
7
- q2rad/q2forms.py,sha256=A5VeBK8OdE3zn0L1TgvCk4OjpB1nLibJqBFfpVZr_Uc,10181
8
- q2rad/q2lines.py,sha256=5KcIh-uxOBfgRsVW30y-lhivSSZSlecmisNMTf5IWpY,16835
9
- q2rad/q2make.py,sha256=wXoyBUwf2zaAl9JjWDCbjAteUElRq0O7ippyaMY9eug,6476
10
- q2rad/q2market.py,sha256=nyIBhZYqxNSlBXpcxdBRQ1vGSzWV8jI4cQoVa9JdRhE,2589
11
- q2rad/q2modules.py,sha256=N3OkUKfiwVZtmDyAtnJcs2Rprd7uIHd0HhjHTyFoN_s,4294
12
- q2rad/q2packages.py,sha256=ifRu8LuVrrTphiJe1JUVED_KB2sHJCPVnZq9VEh3K8w,3473
13
- q2rad/q2queries.py,sha256=ABbr66YRLmleo2wcpvwcQwSPt_htjQsYXgoCqRRQSbo,12512
14
- q2rad/q2rad.py,sha256=6tdOqShosy379Q_5MtTKl4_9vISvYrukT2XVMoM-QdQ,45868
15
- q2rad/q2raddb.py,sha256=ISqT5EBFO7eaXcQRNpA0hMiRU84kbd-FcfckwKMlGfs,4506
16
- q2rad/q2reports.py,sha256=Q-bZONOSDDQPrLziHTpW_L6FS82CkWzxITkv5EX5x98,84439
17
- q2rad/q2stylesettings.py,sha256=_aK-44kFfkaEGdwH7FzRs1KP7nsP08bL8t8OmdjM2eY,4767
18
- q2rad/q2utils.py,sha256=EODL46tMih2tQOV20e5nkNoKeNPyPQZ_YZFk-eAJC2M,19104
19
- q2rad/version.py,sha256=b5gX_HTnsuQMze8B7eGOfsOt1vDe0UEoMwaH1dflSJM,23
20
- q2rad-0.1.201.dist-info/entry_points.txt,sha256=DmsJQE6f3wYuhdN2h6ARYxSe8_d03paeepfGpdVj5rs,42
21
- q2rad-0.1.201.dist-info/LICENSE,sha256=JRR3LlR18ghhYXT4G2cWgXmnxRvcuVcKlqncWWK4MRY,10347
22
- q2rad-0.1.201.dist-info/METADATA,sha256=8EsfMtwlrI5G0iQlxVuXW5V6M1layK13endlCMfyXTQ,3369
23
- q2rad-0.1.201.dist-info/WHEEL,sha256=WGfLGfLX43Ei_YORXSnT54hxFygu34kMpcQdmgmEwCQ,88
24
- q2rad-0.1.201.dist-info/RECORD,,