mirror of
https://github.com/robweber/xbmcbackup.git
synced 2026-01-07 00:04:44 +01:00
Compare commits
8 Commits
matrix-1.6
...
matrix-1.6
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
40b6260521 | ||
|
|
5aad014dbc | ||
|
|
ef3b820ca5 | ||
|
|
76e8e0efeb | ||
|
|
f7e77fd739 | ||
|
|
382dbce4ac | ||
|
|
4b066432be | ||
|
|
d71c923e78 |
16
README.md
16
README.md
@@ -1,13 +1,13 @@
|
||||
# Backup Addon
|
||||
  [](https://travis-ci.com/robweber/xbmcbackup) [](https://github.com/robweber/xbmcbackup/blob/master/LICENSE.txt) [](https://www.python.org/dev/peps/pep-0008/)
|
||||
  [](https://travis-ci.com/robweber/xbmcbackup) [](https://github.com/robweber/xbmcbackup/blob/master/LICENSE.txt) [](https://www.python.org/dev/peps/pep-0008/)
|
||||
|
||||
## About
|
||||
|
||||
I've had to recover my database, thumbnails, and source configuration enough times that I just wanted a quick easy way to back them up. That is what this addon is meant to do.
|
||||
I've had to recover my database, thumbnails, and source configuration enough times that I just wanted a quick easy way to back them up. That is what this addon is meant to do.
|
||||
|
||||
## Running the Program
|
||||
|
||||
Running the program will allow you to select Backup or Restore as a running mode. Selecting Backup will push files to your remote store using the addon settings you defined. Selecting Restore will give you a list of restore points currently in your remote destination. Selecting one will pull the files matching your selection criteria from the restore point to your local Kodi folders.
|
||||
Running the program will allow you to select Backup or Restore as a running mode. Selecting Backup will push files to your remote store using the addon settings you defined. Selecting Restore will give you a list of restore points currently in your remote destination. Selecting one will pull the files matching your selection criteria from the restore point to your local Kodi folders.
|
||||
|
||||
For more specific information please check out the [wiki on Github](https://github.com/robweber/xbmcbackup/wiki) for this project. Advanced descriptions for the following are all there:
|
||||
|
||||
@@ -15,17 +15,9 @@ For more specific information please check out the [wiki on Github](https://gith
|
||||
* [Cloud Storage](https://github.com/robweber/xbmcbackup/wiki/Cloud-Storage)
|
||||
* [Scheduling](https://github.com/robweber/xbmcbackup/wiki/Scheduling)
|
||||
* [Scripting](https://github.com/robweber/xbmcbackup/wiki/Scripting)
|
||||
* [FAQ](https://github.com/robweber/xbmcbackup/wiki/FAQ)
|
||||
* [FAQ](https://github.com/robweber/xbmcbackup/wiki/FAQ)
|
||||
|
||||
|
||||
## Attributions
|
||||
|
||||
Icon files from Open Iconic — www.useiconic.com/open
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<addon id="script.xbmcbackup"
|
||||
name="Backup" version="1.6.6" provider-name="robweber">
|
||||
name="Backup" version="1.6.7" provider-name="robweber">
|
||||
<requires>
|
||||
<import addon="xbmc.python" version="3.0.0"/>
|
||||
<import addon="script.module.dateutil" version="2.8.0" />
|
||||
<import addon="script.module.future" version="0.18.2+matrix.1" />
|
||||
<import addon="script.module.dropbox" version="9.4.0" />
|
||||
<import addon="script.module.pyqrcode" version="1.2.1+matrix.1" />
|
||||
</requires>
|
||||
<extension point="xbmc.python.script" library="default.py">
|
||||
<provides>executable</provides>
|
||||
@@ -89,8 +90,10 @@
|
||||
<screenshot>resources/images/screenshot3.jpg</screenshot>
|
||||
<screenshot>resources/images/screenshot4.jpg</screenshot>
|
||||
</assets>
|
||||
<news>Version 1.6.6
|
||||
- fixed issue with backup rotations not working properly
|
||||
<news>Version 1.6.7
|
||||
- fixed issue with RunScript not launching Advanced Editor in some cases
|
||||
- added qr code for Dropbox setup
|
||||
- fixed error on advanced settings restore
|
||||
</news>
|
||||
</extension>
|
||||
</addon>
|
||||
|
||||
14
changelog.md
14
changelog.md
@@ -4,7 +4,19 @@ All notable changes to this project will be documented in this file.
|
||||
|
||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
|
||||
|
||||
## [Version 1.6.6](https://github.com/robweber/xbmcbackup/compare/matrix-1.6.5...robweber:matrix-1.6.6)
|
||||
## [Version 1.6.7](https://github.com/robweber/xbmcbackup/compare/matrix-1.6.5...robweber:matrix-1.6.7) - 2021-04-16
|
||||
|
||||
### Added
|
||||
|
||||
- added QRcode when setting up Dropbox, uses pyqrcode
|
||||
|
||||
### Fixed
|
||||
|
||||
- fixed issue when using ```RunScript()``` within settings to launch Advanced Editor
|
||||
- error on advanced settings restore prior to reboot
|
||||
- minor gui dialog fixes
|
||||
|
||||
## [Version 1.6.6](https://github.com/robweber/xbmcbackup/compare/matrix-1.6.5...robweber:matrix-1.6.6) - 2021-03-15
|
||||
|
||||
### Fixed
|
||||
|
||||
|
||||
67
default.py
67
default.py
@@ -1,7 +1,37 @@
|
||||
import xbmc
|
||||
import xbmcgui
|
||||
import xbmcvfs
|
||||
import resources.lib.utils as utils
|
||||
from resources.lib.backup import XbmcBackup
|
||||
from resources.lib.authorizers import DropboxAuthorizer
|
||||
from resources.lib.advanced_editor import AdvancedBackupEditor
|
||||
|
||||
# mode constants
|
||||
BACKUP = 0
|
||||
RESTORE = 1
|
||||
SETTINGS = 2
|
||||
ADVANCED_EDITOR = 3
|
||||
LAUNCHER = 4
|
||||
|
||||
|
||||
def authorize_cloud(cloudProvider):
|
||||
# drobpox
|
||||
if(cloudProvider == 'dropbox'):
|
||||
authorizer = DropboxAuthorizer()
|
||||
|
||||
if(authorizer.authorize()):
|
||||
xbmcgui.Dialog().ok(utils.getString(30010), '%s %s' % (utils.getString(30027), utils.getString(30106)))
|
||||
else:
|
||||
xbmcgui.Dialog().ok(utils.getString(30010), '%s %s' % (utils.getString(30107), utils.getString(30027)))
|
||||
|
||||
|
||||
def remove_auth():
|
||||
# triggered from settings.xml - asks if user wants to delete OAuth token information
|
||||
shouldDelete = xbmcgui.Dialog().yesno(utils.getString(30093), utils.getString(30094), utils.getString(30095), autoclose=7000)
|
||||
|
||||
if(shouldDelete):
|
||||
# delete any of the known token file types
|
||||
xbmcvfs.delete(xbmcvfs.translatePath(utils.data_dir() + "tokens.txt")) # dropbox
|
||||
xbmcvfs.delete(xbmcvfs.translatePath(utils.data_dir() + "google_drive.dat")) # google drive
|
||||
|
||||
|
||||
def get_params():
|
||||
@@ -13,6 +43,7 @@ def get_params():
|
||||
if(args.startswith('?')):
|
||||
args = args[1:] # legacy in case of url params
|
||||
splitString = args.split('=')
|
||||
utils.log(splitString[1])
|
||||
param[splitString[0]] = splitString[1]
|
||||
except:
|
||||
pass
|
||||
@@ -24,13 +55,13 @@ def get_params():
|
||||
mode = -1
|
||||
params = get_params()
|
||||
|
||||
|
||||
if("mode" in params):
|
||||
if(params['mode'] == 'backup'):
|
||||
mode = 0
|
||||
mode = BACKUP
|
||||
elif(params['mode'] == 'restore'):
|
||||
mode = 1
|
||||
|
||||
mode = RESTORE
|
||||
elif(params['mode'] == 'launcher'):
|
||||
mode = LAUNCHER
|
||||
|
||||
# if mode wasn't passed in as arg, get from user
|
||||
if(mode == -1):
|
||||
@@ -49,15 +80,30 @@ if(mode != -1):
|
||||
# run the profile backup
|
||||
backup = XbmcBackup()
|
||||
|
||||
if(mode == 2):
|
||||
if(mode == SETTINGS):
|
||||
# open the settings dialog
|
||||
utils.openSettings()
|
||||
elif(mode == 3 and utils.getSettingInt('backup_selection_type') == 1):
|
||||
# open the advanced editor
|
||||
xbmc.executebuiltin('RunScript(special://home/addons/script.xbmcbackup/launcher.py, action=advanced_editor)')
|
||||
elif(mode == ADVANCED_EDITOR and utils.getSettingInt('backup_selection_type') == 1):
|
||||
# open the advanced editor but only if in advanced mode
|
||||
editor = AdvancedBackupEditor()
|
||||
editor.showMainScreen()
|
||||
elif(mode == LAUNCHER):
|
||||
# copied from old launcher.py
|
||||
if(params['action'] == 'authorize_cloud'):
|
||||
authorize_cloud(params['provider'])
|
||||
elif(params['action'] == 'remove_auth'):
|
||||
remove_auth()
|
||||
elif(params['action'] == 'advanced_editor'):
|
||||
editor = AdvancedBackupEditor()
|
||||
editor.showMainScreen()
|
||||
elif(params['action'] == 'advanced_copy_config'):
|
||||
editor = AdvancedBackupEditor()
|
||||
editor.copySimpleConfig()
|
||||
|
||||
elif(backup.remoteConfigured()):
|
||||
|
||||
if(mode == backup.Restore):
|
||||
# if mode was RESTORE
|
||||
if(mode == RESTORE):
|
||||
# get list of valid restore points
|
||||
restorePoints = backup.listBackups()
|
||||
pointNames = []
|
||||
@@ -90,6 +136,7 @@ if(mode != -1):
|
||||
else:
|
||||
backup.restore()
|
||||
else:
|
||||
# mode was BACKUP
|
||||
backup.backup()
|
||||
else:
|
||||
# can't go any further
|
||||
|
||||
58
launcher.py
58
launcher.py
@@ -1,58 +0,0 @@
|
||||
# launcher for various helpful functions found in the settings.xml area
|
||||
import sys
|
||||
import xbmcgui
|
||||
import xbmcvfs
|
||||
import resources.lib.utils as utils
|
||||
from resources.lib.authorizers import DropboxAuthorizer
|
||||
from resources.lib.advanced_editor import AdvancedBackupEditor
|
||||
|
||||
|
||||
def authorize_cloud(cloudProvider):
|
||||
# drobpox
|
||||
if(cloudProvider == 'dropbox'):
|
||||
authorizer = DropboxAuthorizer()
|
||||
|
||||
if(authorizer.authorize()):
|
||||
xbmcgui.Dialog().ok(utils.getString(30010), '%s %s' % (utils.getString(30027), utils.getString(30106)))
|
||||
else:
|
||||
xbmcgui.Dialog().ok(utils.getString(30010), '%s %s' % (utils.getString(30107), utils.getString(30027)))
|
||||
|
||||
|
||||
def remove_auth():
|
||||
# triggered from settings.xml - asks if user wants to delete OAuth token information
|
||||
shouldDelete = xbmcgui.Dialog().yesno(utils.getString(30093), utils.getString(30094), utils.getString(30095), autoclose=7000)
|
||||
|
||||
if(shouldDelete):
|
||||
# delete any of the known token file types
|
||||
xbmcvfs.delete(xbmcvfs.translatePath(utils.data_dir() + "tokens.txt")) # dropbox
|
||||
xbmcvfs.delete(xbmcvfs.translatePath(utils.data_dir() + "google_drive.dat")) # google drive
|
||||
|
||||
|
||||
def get_params():
|
||||
param = {}
|
||||
try:
|
||||
for i in sys.argv:
|
||||
args = i
|
||||
if('=' in args):
|
||||
if(args.startswith('?')):
|
||||
args = args[1:] # legacy in case of url params
|
||||
splitString = args.split('=')
|
||||
param[splitString[0]] = splitString[1]
|
||||
except:
|
||||
pass
|
||||
|
||||
return param
|
||||
|
||||
|
||||
params = get_params()
|
||||
|
||||
if(params['action'] == 'authorize_cloud'):
|
||||
authorize_cloud(params['provider'])
|
||||
elif(params['action'] == 'remove_auth'):
|
||||
remove_auth()
|
||||
elif(params['action'] == 'advanced_editor'):
|
||||
editor = AdvancedBackupEditor()
|
||||
editor.showMainScreen()
|
||||
elif(params['action'] == 'advanced_copy_config'):
|
||||
editor = AdvancedBackupEditor()
|
||||
editor.copySimpleConfig()
|
||||
@@ -213,8 +213,8 @@ msgid "Removing backup"
|
||||
msgstr "Removing backup"
|
||||
|
||||
msgctxt "#30056"
|
||||
msgid "Go to this URL to authorize"
|
||||
msgstr "Go to this URL to authorize"
|
||||
msgid "Scan or click this URL to authorize, click OK AFTER completion"
|
||||
msgstr "Scan or click this URL to authorize, click OK AFTER completion"
|
||||
|
||||
msgctxt "#30057"
|
||||
msgid "Click OK AFTER completion"
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import xbmcgui
|
||||
import xbmcvfs
|
||||
import pyqrcode
|
||||
import resources.lib.tinyurl as tinyurl
|
||||
import resources.lib.utils as utils
|
||||
|
||||
@@ -11,6 +12,30 @@ except ImportError:
|
||||
pass
|
||||
|
||||
|
||||
class QRCode(xbmcgui.WindowXMLDialog):
|
||||
def __init__(self, *args, **kwargs):
|
||||
self.image = kwargs["image"]
|
||||
self.text = kwargs["text"]
|
||||
self.url = kwargs['url']
|
||||
|
||||
def onInit(self):
|
||||
self.imagecontrol = 501
|
||||
self.textbox1 = 502
|
||||
self.textbox2 = 504
|
||||
self.okbutton = 503
|
||||
self.showdialog()
|
||||
|
||||
def showdialog(self):
|
||||
self.getControl(self.imagecontrol).setImage(self.image)
|
||||
self.getControl(self.textbox1).setText(self.text)
|
||||
self.getControl(self.textbox2).setText(self.url)
|
||||
self.setFocus(self.getControl(self.okbutton))
|
||||
|
||||
def onClick(self, controlId):
|
||||
if (controlId == self.okbutton):
|
||||
self.close()
|
||||
|
||||
|
||||
class DropboxAuthorizer:
|
||||
APP_KEY = ""
|
||||
APP_SECRET = ""
|
||||
@@ -52,7 +77,20 @@ class DropboxAuthorizer:
|
||||
|
||||
# print url in log
|
||||
utils.log("Authorize URL: " + url)
|
||||
xbmcgui.Dialog().ok(utils.getString(30010), '%s\n%s\n%s' % (utils.getString(30056), utils.getString(30057), str(tinyurl.shorten(url), 'utf-8')))
|
||||
|
||||
# create a QR Code
|
||||
shortUrl = str(tinyurl.shorten(url), 'utf-8')
|
||||
imageFile = xbmcvfs.translatePath(utils.data_dir() + '/qrcode.png')
|
||||
qrIMG = pyqrcode.create(shortUrl)
|
||||
qrIMG.png(imageFile, scale=10)
|
||||
|
||||
# show the dialog prompt to authorize
|
||||
qr = QRCode("script-backup-qrcode.xml", utils.addon_dir(), "default", image=imageFile, text=utils.getString(30056), url=shortUrl)
|
||||
qr.doModal()
|
||||
|
||||
# cleanup
|
||||
del qr
|
||||
xbmcvfs.delete(imageFile)
|
||||
|
||||
# get the auth code
|
||||
code = xbmcgui.Dialog().input(utils.getString(30027) + ' ' + utils.getString(30103))
|
||||
|
||||
@@ -272,10 +272,12 @@ class XbmcBackup:
|
||||
# check for the existance of an advancedsettings file
|
||||
if(self.remote_vfs.exists(self.remote_vfs.root_path + "config/advancedsettings.xml") and not self.skip_advanced):
|
||||
# let the user know there is an advanced settings file present
|
||||
restartXbmc = xbmcgui.Dialog().yesno(utils.getString(30038), "%s\n%s" % (utils.getString(30039), utils.getString(30040)), utils.getString(30041))
|
||||
restartXbmc = xbmcgui.Dialog().yesno(utils.getString(30038), "%s\n%s\n%s" % (utils.getString(30039), utils.getString(30040), utils.getString(30041)))
|
||||
|
||||
if(restartXbmc):
|
||||
# add only this file to the file list
|
||||
self.transferSize = 1
|
||||
self.transferLeft = 1
|
||||
fileManager.addFile(self.remote_vfs.root_path + "config/advancedsettings.xml")
|
||||
self._copyFiles(fileManager.getFiles(), self.remote_vfs, self.xbmc_vfs)
|
||||
|
||||
|
||||
@@ -22,6 +22,21 @@ class BackupScheduler:
|
||||
self.enabled = utils.getSettingBool("enable_scheduler")
|
||||
self.next_run_path = xbmcvfs.translatePath(utils.data_dir()) + 'next_run.txt'
|
||||
|
||||
# display upgrade messages if they exist
|
||||
if(utils.getSettingInt('upgrade_notes') < UPGRADE_INT):
|
||||
xbmcgui.Dialog().ok(utils.getString(30010), utils.getString(30132))
|
||||
utils.setSetting('upgrade_notes', str(UPGRADE_INT))
|
||||
|
||||
# check if a backup should be resumed
|
||||
resumeRestore = self._resumeCheck()
|
||||
|
||||
if(resumeRestore):
|
||||
restore = XbmcBackup()
|
||||
restore.selectRestore(self.restore_point)
|
||||
# skip the advanced settings check
|
||||
restore.skipAdvanced()
|
||||
restore.restore()
|
||||
|
||||
if(self.enabled):
|
||||
|
||||
# sleep for 2 minutes so Kodi can start and time can update correctly
|
||||
@@ -56,21 +71,6 @@ class BackupScheduler:
|
||||
|
||||
def start(self):
|
||||
|
||||
# display upgrade messages if they exist
|
||||
if(utils.getSettingInt('upgrade_notes') < UPGRADE_INT):
|
||||
xbmcgui.Dialog().ok(utils.getString(30010), utils.getString(30132))
|
||||
utils.setSetting('upgrade_notes', str(UPGRADE_INT))
|
||||
|
||||
# check if a backup should be resumed
|
||||
resumeRestore = self._resumeCheck()
|
||||
|
||||
if(resumeRestore):
|
||||
restore = XbmcBackup()
|
||||
restore.selectRestore(self.restore_point)
|
||||
# skip the advanced settings check
|
||||
restore.skipAdvanced()
|
||||
restore.restore()
|
||||
|
||||
while(not self.monitor.abortRequested()):
|
||||
|
||||
if(self.enabled):
|
||||
@@ -178,7 +178,7 @@ class BackupScheduler:
|
||||
self.restore_point = rFile.read()
|
||||
rFile.close()
|
||||
xbmcvfs.delete(xbmcvfs.translatePath(utils.data_dir() + "resume.txt"))
|
||||
shouldContinue = xbmcgui.Dialog().yesno(utils.getString(30042), utils.getString(30043), utils.getString(30044))
|
||||
shouldContinue = xbmcgui.Dialog().yesno(utils.getString(30042), "%s\n%s" % (utils.getString(30043), utils.getString(30044)))
|
||||
|
||||
return shouldContinue
|
||||
|
||||
|
||||
@@ -147,7 +147,7 @@
|
||||
<dependency type="visible" setting="remote_selection">2</dependency>
|
||||
</dependencies>
|
||||
<control type="button" format="action">
|
||||
<data>RunScript(special://home/addons/script.xbmcbackup/launcher.py,action=authorize_cloud,provider=dropbox)</data>
|
||||
<data>RunScript(script.xbmcbackup,mode=launcher,action=authorize_cloud,provider=dropbox)</data>
|
||||
</control>
|
||||
</setting>
|
||||
</group>
|
||||
@@ -160,7 +160,7 @@
|
||||
<dependency type="visible" setting="remote_selection">2</dependency>
|
||||
</dependencies>
|
||||
<control type="button" format="action">
|
||||
<data>RunScript(special://home/addons/script.xbmcbackup/launcher.py,action=remove_auth)</data>
|
||||
<data>RunScript(script.xbmcbackup,mode=launcher,action=remove_auth)</data>
|
||||
</control>
|
||||
</setting>
|
||||
</group>
|
||||
@@ -252,7 +252,7 @@
|
||||
<dependency type="visible" setting="backup_selection_type">1</dependency>
|
||||
</dependencies>
|
||||
<control type="button" format="action">
|
||||
<data>RunScript(special://home/addons/script.xbmcbackup/launcher.py,action=advanced_editor)</data>
|
||||
<data>RunScript(script.xbmcbackup,mode=launcher,action=advanced_editor)</data>
|
||||
</control>
|
||||
</setting>
|
||||
<setting id="advanced_defaults" type="action" label="30139" help="">
|
||||
@@ -262,7 +262,7 @@
|
||||
<dependency type="visible" setting="backup_selection_type">1</dependency>
|
||||
</dependencies>
|
||||
<control type="button" format="action">
|
||||
<data>RunScript(special://home/addons/script.xbmcbackup/launcher.py,action=advanced_copy_config)</data>
|
||||
<data>RunScript(script.xbmcbackup,mode=launcher,action=advanced_copy_config)</data>
|
||||
</control>
|
||||
</setting>
|
||||
</group>
|
||||
|
||||
74
resources/skins/default/1080i/script-backup-qrcode.xml
Normal file
74
resources/skins/default/1080i/script-backup-qrcode.xml
Normal file
@@ -0,0 +1,74 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<window>
|
||||
<coordinates>
|
||||
<left>502</left>
|
||||
<top>345</top>
|
||||
</coordinates>
|
||||
<controls>
|
||||
<animation type="WindowOpen" reversible="false">
|
||||
<effect type="zoom" start="80" end="100" center="960,540" delay="160" tween="back" time="240" />
|
||||
<effect type="fade" delay="160" end="100" time="240" />
|
||||
</animation>
|
||||
<animation type="WindowClose" reversible="false">
|
||||
<effect type="zoom" start="100" end="80" center="960,540" easing="in" tween="back" time="240" />
|
||||
<effect type="fade" start="100" end="0" time="240" />
|
||||
</animation>
|
||||
<control type="image">
|
||||
<left>-1920</left>
|
||||
<top>-1080</top>
|
||||
<width>5760</width>
|
||||
<height>3240</height>
|
||||
<animation effect="fade" start="0" end="100" time="300">WindowOpen</animation>
|
||||
<animation effect="fade" start="100" end="0" time="200">WindowClose</animation>
|
||||
<texture colordiffuse="C2FFFFFF">background-black.png</texture>
|
||||
</control>
|
||||
<control type="image">
|
||||
<left>0</left>
|
||||
<top>0</top>
|
||||
<width>915</width>
|
||||
<height>450</height>
|
||||
<texture border="2">dialog-bg.png</texture>
|
||||
</control>
|
||||
<control type="textbox" id="502">
|
||||
<left>0</left>
|
||||
<top>20</top>
|
||||
<width>915</width>
|
||||
<height>300</height>
|
||||
<font>font12_title</font>
|
||||
<align>center</align>
|
||||
<aligny>top</aligny>
|
||||
<shadowcolor>FF000000</shadowcolor>
|
||||
</control>
|
||||
<control type="textbox" id="504">
|
||||
<left>0</left>
|
||||
<top>60</top>
|
||||
<width>915</width>
|
||||
<height>300</height>
|
||||
<font>font12_title</font>
|
||||
<align>center</align>
|
||||
<aligny>top</aligny>
|
||||
<shadowcolor>FF000000</shadowcolor>
|
||||
</control>
|
||||
<control type="image" id="501">
|
||||
<left>300</left>
|
||||
<top>80</top>
|
||||
<width>300</width>
|
||||
<height>300</height>
|
||||
<aspectratio aligny="center" align="center">keep</aspectratio>
|
||||
</control>
|
||||
<control type="button" id="503">
|
||||
<left>302</left>
|
||||
<top>350</top>
|
||||
<width>300</width>
|
||||
<height>90</height>
|
||||
<font>font12_title</font>
|
||||
<textcolor>FFF0F0F0</textcolor>
|
||||
<textoffsetx>20</textoffsetx>
|
||||
<label>OK</label>
|
||||
<align>center</align>
|
||||
<aligny>center</aligny>
|
||||
<texturefocus border="40" colordiffuse="FF12B2E7">dialogbutton-fo.png</texturefocus>
|
||||
<texturenofocus border="40">dialogbutton-nofo.png</texturenofocus>
|
||||
</control>
|
||||
</controls>
|
||||
</window>
|
||||
BIN
resources/skins/default/media/background-black.png
Normal file
BIN
resources/skins/default/media/background-black.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 166 B |
BIN
resources/skins/default/media/dialog-bg.png
Normal file
BIN
resources/skins/default/media/dialog-bg.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.8 KiB |
BIN
resources/skins/default/media/dialogbutton-fo.png
Normal file
BIN
resources/skins/default/media/dialogbutton-fo.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.1 KiB |
BIN
resources/skins/default/media/dialogbutton-nofo.png
Normal file
BIN
resources/skins/default/media/dialogbutton-nofo.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.1 KiB |
Reference in New Issue
Block a user