Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Add functions or folders to a .qml file
#1
I want to modify the file named System.qml on the desktop to implement the following functions:
(Copy the System.qml file from the QM installation directory to the desktop, and remove the file's read-only attribute.)

1. Add a function named FileCopy2 after the function named FileCopy. The function content is: "I am the newly added function FileCopy2";

2. Create a folder named __Add under the folder named priveate, and add a function named AddTest. The function content is: "I am the newly added function AddTest".

After the following qm code is executed, it shows success, but an error is reported when opening the file:
Failed to open file 'C:\Users\Administrator\Desktop\System.qml'. Error reading items: The file is corrupt

Macro qml_mod
Code:
Copy      Help
out

str dbfile="$desktop$\System.qml"
Sqlite db.Open(dbfile)

;; ===== 1. Add FileCopy2 function to File folder (pid=81) =====
SqliteStatement chk
chk.Prepare(db "SELECT rowid FROM items WHERE name='FileCopy2' AND pid=81;")
if chk.FetchRow
,out "FileCopy2 already exists, skip"
,chk.Delete
else
,chk.Delete
,;; Insert items record
,db.Exec("INSERT INTO items (pid, ord, flags, name, trigger, icon, td, guid) VALUES (81, NULL, 16777218, 'FileCopy2', NULL, NULL, NULL, randomblob(16));")
,;; Get the newly inserted rowid
,SqliteStatement tmp
,tmp.Prepare(db "SELECT last_insert_rowid();")
,tmp.FetchRow
,int newRowid = tmp.GetInt(0)
,tmp.Delete
,;; Insert texts record, rowid must be the same
,str ftext="[]I am the newly added function FileCopy2"
,ftext.SqlEscape
,str sqlText=F"INSERT INTO texts (rowid, id, date, text) VALUES ({newRowid}, {newRowid}, NULL, '{ftext}');"
,db.Exec(sqlText)
,out "Added FileCopy2"

;; ===== 2. Create __Add folder under root private folder (id=952, pid=0) =====
SqliteStatement chk2
chk2.Prepare(db "SELECT rowid FROM items WHERE name='__Add' AND pid=952;")
if chk2.FetchRow
,int folderRowid = chk2.GetInt(0)
,out "__Add folder already exists"
,chk2.Delete
else
,chk2.Delete
,;; Insert folder items record
,db.Exec("INSERT INTO items (pid, ord, flags, name, trigger, icon, td, guid) VALUES (952, NULL, 131078, '__Add', NULL, NULL, NULL, randomblob(16));")
,;; Get the newly inserted rowid
,SqliteStatement tmp2
,tmp2.Prepare(db "SELECT last_insert_rowid();")
,tmp2.FetchRow
,folderRowid = tmp2.GetInt(0)
,tmp2.Delete
,;; Insert empty texts record (folders also need one)
,str emptyText=""
,emptyText.SqlEscape
,str sqlFolderText=F"INSERT INTO texts (rowid, id, date, text) VALUES ({folderRowid}, {folderRowid}, NULL, '{emptyText}');"
,db.Exec(sqlFolderText)
,out F"Created __Add folder, rowid={folderRowid}"

;; ===== 3. Add AddTest function under __Add folder =====
SqliteStatement chk3
chk3.Prepare(db F"SELECT rowid FROM items WHERE name='AddTest' AND pid={folderRowid};")
if chk3.FetchRow
,out "AddTest already exists"
,chk3.Delete
else
,chk3.Delete
,;; Insert items record
,db.Exec(F"INSERT INTO items (pid, ord, flags, name, trigger, icon, td, guid) VALUES ({folderRowid}, NULL, 16777218, 'AddTest', NULL, NULL, NULL, randomblob(16));")
,;; Get the newly inserted rowid
,SqliteStatement tmp3
,tmp3.Prepare(db "SELECT last_insert_rowid();")
,tmp3.FetchRow
,int addRowid = tmp3.GetInt(0)
,tmp3.Delete
,;; Insert texts record
,str atext="[]I am the newly added function AddTest"
,atext.SqlEscape
,str sqlAddText=F"INSERT INTO texts (rowid, id, date, text) VALUES ({addRowid}, {addRowid}, NULL, '{atext}');"
,db.Exec(sqlAddText)
,out "Added AddTest"

db.Close
out "Operation completed, please reopen System.qml to verify."

[Image: 1.png]


[Image: 2.png]
#2
Attached - non-readonly System.qml. Replace your System.qml. Then can edit in QM.


Attached Files
.zip   System.zip (Size: 632.72 KB / Downloads: 3)
#3
Thank you so much!

Can you tell me how to set the System.qml file to read-only again?
I set the file attribute to read-only, which helps a bit, but I'm still afraid of accidentally messing up the source code in the future.

Or give me some relevant hints, and I'll use ChatGPT to help solve it. I've found that as long as I provide it with enough information and examples, I can almost always get the answer I want.
#4
I use the attached non-readonly System.qml on my QM development computer. When releasing a new QM version, I save it as read-only (it's a SQLite database feature).

Found this macro. Makes System.qml read-only or non-read-only. Make exe and run the exe not from QM.
Macro System read-only
Code:
Copy      Help
int ro
sel mes("Make System.qml read-only?[][]This will restart QM." "" "YNC")
,case 'Y' ro=1
,case 'N'
,case else ret

int w=win("" "QM_Editor")
if w
,PostMessage w WM_CLOSE 1 0
,wait 0 WP w

str sf="$qm$\system.qml"
SetAttr sf FILE_ATTRIBUTE_READONLY 2

Sqlite x.Open(sf)
x.Exec(F"PRAGMA journal_mode={iif(ro `DELETE` `WAL`)}")
x.Close

if(ro) SetAttr sf FILE_ATTRIBUTE_READONLY 1

if w
,run "C:\code\qm\qm.exe" "v"

;BEGIN PROJECT
;main_function  System read-only
;exe_file  $qm$\System read-only.exe
;icon  <default>
;manifest  $qm$\default.exe.manifest
;flags  4
;guid  {76620DF9-3AC6-4306-A27C-7340D1F437AA}
;END PROJECT


Forum Jump:


Users browsing this thread: 1 Guest(s)