PageRenderTime 64ms CodeModel.GetById 25ms RepoModel.GetById 0ms app.codeStats 1ms

/marave/main.py

http://marave.googlecode.com/
Python | 1511 lines | 1382 code | 93 blank | 36 comment | 152 complexity | add3752190e8932fc21b6ce56c184869 MD5 | raw file
Possible License(s): GPL-2.0, BSD-2-Clause

Large files files are truncated, but you can click here to view the full file

  1. #-*- coding: utf-8 -*-
  2. """The user interface for our app"""
  3. # Marave, a relaxing text editor.
  4. # Copyright (C) 2010 Roberto Alsina <ralsina@netmanagers.com.ar>
  5. # This program is free software; you can redistribute it and/or modify
  6. # it under the terms of the GNU General Public License as published by
  7. # the Free Software Foundation; either version 2 of the License
  8. # This program is distributed in the hope that it will be useful,
  9. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. # GNU General Public License for more details.
  12. # You should have received a copy of the GNU General Public License along
  13. # with this program; if not, write to the Free Software Foundation, Inc.,
  14. # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  15. import os, sys, codecs, re, optparse
  16. from functools import partial
  17. if hasattr(sys, 'frozen'):
  18. PATH = os.path.abspath(os.path.dirname(sys.executable))
  19. else:
  20. PATH = os.path.abspath(os.path.dirname(__file__))
  21. FORCE45=os.getenv('FORCE45') or False
  22. if FORCE45:
  23. print 'Forcing Qt 4.5 mode'
  24. ANIMATIONS=True
  25. # Import Qt modules
  26. from PyQt4 import QtCore, QtGui, QtSvg
  27. # Try to import Phonon from PyQt or PyKDE
  28. SOUND=False
  29. try:
  30. from PyQt4.phonon import Phonon
  31. SOUND=True
  32. except ImportError:
  33. try:
  34. from PyKDE4.phonon import Phonon
  35. SOUND=True
  36. except ImportError:
  37. pass
  38. sys.path.append(PATH)
  39. from plugins.plugins import Plugin
  40. # Syntax highlight support
  41. try:
  42. from editor.highlight.SyntaxHighlighter import srchiliteqt
  43. except ImportError:
  44. srchiliteqt = None
  45. from editor import Editor
  46. from Ui_prefs import Ui_Form as UI_Prefs
  47. class Handle(QtGui.QGraphicsRectItem):
  48. def __init__(self,x,y,w,h):
  49. QtGui.QGraphicsRectItem.__init__(self,x,y,w,h)
  50. self.setBrush(QtGui.QColor(100,100,100,80))
  51. self.setPen(QtGui.QColor(0,0,0,0))
  52. self.proxy=self
  53. class PrefsWidget(QtGui.QWidget):
  54. def __init__(self, scene, mainwindow=None):
  55. QtGui.QWidget.__init__(self)
  56. # Set up the UI from designer
  57. self.mainwindow=mainwindow
  58. self.ui=UI_Prefs()
  59. self.proxy=scene.addWidget(self)
  60. self.ui.setupUi(self)
  61. self.loadthemelist()
  62. self.loadstylelist()
  63. self.loadSpellcheckers()
  64. self.loadLexers()
  65. self.loadPlugins()
  66. self.proxy.setZValue(100)
  67. self.proxy.setFlag(QtGui.QGraphicsItem.ItemIsMovable, False)
  68. self.proxy.setOpacity(0)
  69. def loadPlugins(self):
  70. Plugin.initPlugins()
  71. classes = Plugin.listPlugins()
  72. enabled = self.mainwindow.settings.value('enabledplugins')
  73. if enabled.isValid():
  74. enabled=unicode(enabled.toString()).split(',')
  75. else:
  76. enabled=[]
  77. self.mainwindow.layoutButtons()
  78. self.enablers=[ partial (p.enable,client=self.mainwindow) for p in classes]
  79. self.configers=[ partial (p.showConfig, client=self.mainwindow) for p in classes]
  80. for p,e,c in zip(classes, self.enablers, self.configers):
  81. sel=p.selectorWidget()
  82. if p.name in enabled:
  83. sel.check.setChecked(True)
  84. sel.check.toggled.connect(e)
  85. sel.conf.clicked.connect(c)
  86. self.ui.pluginLayout.addWidget(sel)
  87. self.ui.pluginLayout.addStretch(10)
  88. def loadLexers(self):
  89. self._l={}
  90. if srchiliteqt:
  91. self._langs=srchiliteqt.LanguageComboBox()
  92. self._styles=srchiliteqt.StyleComboBox()
  93. self.ui.syntaxList.clear()
  94. for i in range(self._langs.count()):
  95. t=unicode(self._langs.itemText(i))
  96. if t:
  97. self.ui.syntaxList.addItem(t.split('.')[0])
  98. self._l['lang-'+t.split('.')[0]]=t
  99. self.ui.schemeList.clear()
  100. for i in range(self._styles.count()):
  101. t=unicode(self._styles.itemText(i))
  102. if t:
  103. self.ui.schemeList.addItem(t.split('.')[0])
  104. self._l['scheme-'+t.split('.')[0]]=t
  105. def loadSpellcheckers(self):
  106. self.ui.langBox.clear()
  107. self.ui.langBox.addItem(self.tr('None'))
  108. try:
  109. import enchant
  110. for l, _ in enchant.Broker().list_dicts():
  111. self.ui.langBox.addItem(l)
  112. except ImportError:
  113. self.ui.langBox.setEnabled(False)
  114. def loadthemelist(self):
  115. self.ui.themeList.clear()
  116. self.ui.themeList.addItem(self.tr('Current'))
  117. tdir=os.path.join(PATH,'themes')
  118. l=os.listdir(tdir)
  119. l.sort()
  120. for t in l:
  121. if t.startswith('.') or t.endswith('~'):
  122. continue
  123. self.ui.themeList.addItem(t)
  124. def loadstylelist(self):
  125. self.ui.styleList.clear()
  126. sdir=os.path.join(PATH,'stylesheets')
  127. l=os.listdir(sdir)
  128. l.sort()
  129. for t in l:
  130. if t.startswith('.') or t.endswith('~'):
  131. continue
  132. self.ui.styleList.addItem(t)
  133. class MenuStrip(QtGui.QGraphicsWidget):
  134. def __init__(self, scene):
  135. QtGui.QGraphicsWidget.__init__(self)
  136. self.proxy=self
  137. scene.addItem(self)
  138. self.proxy.setZValue(100)
  139. self.proxy.setFlag(QtGui.QGraphicsItem.ItemDoesntPropagateOpacityToChildren, True)
  140. self.proxy.setFlag(QtGui.QGraphicsItem.ItemIsMovable, False)
  141. self.setPos=self.proxy.setPos
  142. self.proxy.setOpacity(100)
  143. buttons=[]
  144. def fadein(thing, target=1., thendo=None):
  145. if not ANIMATIONS:
  146. if isinstance(thing, QtGui.QGraphicsItem):
  147. w = thing
  148. else:
  149. w = thing.proxy
  150. w.setOpacity(target)
  151. if thendo: thendo()
  152. return
  153. if not FORCE45 and (isinstance (thing, QtCore.QObject) and QtCore.QT_VERSION_STR >= '4.6.0'):
  154. thing.anim=QtCore.QPropertyAnimation(thing.proxy, "opacity")
  155. thing.anim.setDuration(200)
  156. thing.anim.setStartValue(thing.proxy.opacity())
  157. thing.anim.setEndValue(target)
  158. thing.anim.start()
  159. thing.anim.finished.connect(thing.anim.deleteLater)
  160. if thendo:
  161. thing.anim.finished.connect(thendo)
  162. else:
  163. if isinstance(thing, QtGui.QGraphicsItem):
  164. w = thing
  165. else:
  166. w = thing.proxy
  167. w.show()
  168. w.startOpacity = w.opacity()
  169. w.endOpacity = target
  170. def animateOpacity(v):
  171. op = v*(w.endOpacity-w.startOpacity)+w.startOpacity
  172. w.setOpacity(op)
  173. def animationFinished():
  174. if(w.endOpacity == 0):
  175. w.hide()
  176. if thendo: thendo()
  177. thing.tline = QtCore.QTimeLine(200)
  178. thing.tline.setCurveShape(QtCore.QTimeLine.LinearCurve)
  179. thing.tline.valueChanged.connect(animateOpacity)
  180. thing.tline.finished.connect(animationFinished)
  181. thing.tline.start()
  182. def fadeout(thing, thendo=None):
  183. fadein(thing, 0, thendo)
  184. def animheight(thing, target, thendo=None, animate=True):
  185. if ANIMATIONS and (FORCE45 or (isinstance (thing, QtCore.QObject) and QtCore.QT_VERSION_STR >= '4.6.0')):
  186. thing.hanim=QtCore.QPropertyAnimation(thing.proxy, "geometry")
  187. thing.hanim.setDuration(200)
  188. g1=thing.geometry()
  189. g1.setHeight(target)
  190. thing.hanim.setStartValue(thing.geometry())
  191. thing.hanim.setEndValue(g1)
  192. thing.hanim.start()
  193. thing.hanim.finished.connect(thing.hanim.deleteLater)
  194. if thendo:
  195. thing.hanim.finished.connect(thendo)
  196. else:
  197. thing.resize(thing.width(),target)
  198. if thendo:
  199. thendo()
  200. class FunkyButton(QtGui.QPushButton):
  201. def __init__(self, icon, text, scene, name=None):
  202. # Special case: in RTL apps, 'previous' and 'next' are reversed:
  203. if QtCore.QCoreApplication.instance().isRightToLeft():
  204. if icon=='previous.svg':
  205. icon='next.svg'
  206. elif icon=='next.svg':
  207. icon='previous.svg'
  208. QtGui.QPushButton.__init__(self,QtGui.QIcon(os.path.join(PATH,'icons',icon)),"")
  209. self.setAttribute(QtCore.Qt.WA_Hover, True)
  210. self.setAttribute(QtCore.Qt.WA_TranslucentBackground, True)
  211. self.proxy=scene.addWidget(self)
  212. self.setFocusPolicy(QtCore.Qt.NoFocus)
  213. self.setMouseTracking(True)
  214. self.children=[]
  215. self.icon=icon
  216. self.text=text
  217. if name is None:
  218. name=text
  219. self.setObjectName(name)
  220. buttons.append(self)
  221. self.proxy.setOpacity(0)
  222. def showChildren(self):
  223. for c in self.children:
  224. c.show()
  225. fadein(c,.7)
  226. def hideChildren(self):
  227. for c in self.children:
  228. fadeout(c)
  229. class FunkyFontList(QtGui.QFontComboBox):
  230. def __init__(self, scene):
  231. QtGui.QFontComboBox.__init__(self)
  232. self.setAttribute(QtCore.Qt.WA_TranslucentBackground, True)
  233. self.setSizePolicy(QtGui.QSizePolicy.Expanding,QtGui.QSizePolicy.Expanding)
  234. self.proxy=scene.addWidget(self)
  235. self.setFocusPolicy(QtCore.Qt.NoFocus)
  236. self.proxy.setOpacity(0)
  237. class FunkyStatusBar(QtGui.QStatusBar):
  238. def __init__(self, scene):
  239. QtGui.QStatusBar.__init__(self)
  240. self.proxy=scene.addWidget(self)
  241. self.setAttribute(QtCore.Qt.WA_TranslucentBackground, True)
  242. self.setFocusPolicy(QtCore.Qt.NoFocus)
  243. self.setSizeGripEnabled(False)
  244. class FunkyEditor(Editor):
  245. def __init__(self, parent, canvaseditor=None):
  246. # This is for Issue 28
  247. self.autoResize=True
  248. self.canvaseditor=canvaseditor
  249. if self.canvaseditor is None:
  250. if FORCE45 or (QtCore.QCoreApplication.instance().style().objectName() == 'oxygen' \
  251. and QtCore.QT_VERSION_STR < '4.6.0'):
  252. self.canvaseditor = False
  253. self.proxy = self
  254. else:
  255. self.canvaseditor = True
  256. if not self.canvaseditor:
  257. print 'Using non-canvas editor'
  258. Editor.__init__(self, parent)
  259. self.setMouseTracking(True)
  260. self.viewport().setMouseTracking(True)
  261. self.defSize=self.font().pointSize()
  262. # This is for Issue 20
  263. else:
  264. print 'Using canvas editor'
  265. Editor.__init__(self)
  266. self.setMouseTracking(True)
  267. self.viewport().setMouseTracking(True)
  268. self.defSize=self.font().pointSize()
  269. self.docName=''
  270. self.proxy=parent._scene.addWidget(self)
  271. self.proxy.setOpacity(1)
  272. self.setFocusPolicy(QtCore.Qt.StrongFocus)
  273. self.parent=lambda: parent
  274. self.proxy.setFlag(QtGui.QGraphicsItem.ItemIsMovable, False)
  275. class BGItem(QtGui.QGraphicsPixmapItem):
  276. def __init__(self):
  277. QtGui.QGraphicsPixmapItem.__init__(self)
  278. class MainWidget (QtGui.QGraphicsView):
  279. def __init__(self, opengl=False, canvaseditor=None):
  280. QtGui.QGraphicsView.__init__(self)
  281. self.setWindowIcon(QtGui.QIcon(os.path.join(PATH,'icons','marave.svg')))
  282. self.setGeometry(QtCore.QCoreApplication.instance().desktop().screenGeometry(self))
  283. self._scene=QtGui.QGraphicsScene()
  284. self.setObjectName ("Main")
  285. if opengl:
  286. if FORCE45 or (QtCore.QCoreApplication.instance().style().objectName() == 'oxygen' \
  287. and QtCore.QT_VERSION_STR < '4.6.0'):
  288. print "OpenGL acceleration doesn't work well with Oxygen, disabling it"
  289. else:
  290. try:
  291. from PyQt4 import QtOpenGL
  292. self.setViewport(QtOpenGL.QGLWidget())
  293. except ImportError:
  294. print 'Qt OpenGL support not available'
  295. self.setScene(self._scene)
  296. self.settings=QtCore.QSettings('NetManagers','Marave')
  297. #
  298. self.changing=False
  299. self.visibleWidget=None
  300. self.buttonsHidden = True
  301. # Used for margins and border sizes
  302. self.m=5
  303. # FIXME: self.minW should be a reasonable value based on text size
  304. # or something.
  305. self.minW=100*self.m
  306. self.minH=80*self.m
  307. self.hasSize=False
  308. self.editor=None
  309. self.setMouseTracking(True)
  310. self.currentBG=None
  311. self.currentClick=None
  312. self.currentStation=None
  313. self.bgcolor=None
  314. self.fontcolor=None
  315. self.bg=None
  316. self.bgItem=BGItem()
  317. self.bgItem.setZValue(-1000)
  318. self._scene.addItem(self.bgItem)
  319. self.notifBar=FunkyStatusBar(self._scene)
  320. self.notifBar.messageChanged.connect(self.notifChanged)
  321. self.beep=None
  322. self.music=None
  323. self.buttonStyle=0
  324. self.lang=None
  325. #self.mainMenu=QtGui.QGraphicsWidget()
  326. self.mainMenu=MenuStrip(self._scene)
  327. #self._scene.addItem(self.mainMenu)
  328. self.stations=[x.strip() for x in open(os.path.join(PATH,'radios.txt')).readlines()]
  329. self.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
  330. self.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
  331. # These are the positions for the elements of the screen
  332. # They are recalculated on resize
  333. self.editorX=100
  334. self.editorY=40
  335. self.editorH=400
  336. self.editorW=400
  337. self.editor=FunkyEditor(self, canvaseditor)
  338. self.editor.show()
  339. self.editor.setMouseTracking(True)
  340. self.editor.setFrameStyle(QtGui.QFrame.NoFrame)
  341. self.editor.langChanged.connect(self.editorLangChanged)
  342. # Keyboard shortcuts
  343. self.sc1 = QtGui.QShortcut(QtGui.QKeySequence(self.tr("Ctrl+F","Find")), self);
  344. self.sc1.activated.connect(self.showsearch)
  345. self.sc1b = QtGui.QShortcut(QtGui.QKeySequence(self.tr("Ctrl+R","Find and Replace")), self);
  346. self.sc1b.activated.connect(self.showsearchreplace)
  347. # Taj mode!
  348. self.sc2 = QtGui.QShortcut(QtGui.QKeySequence(self.tr("Ctrl+T","Taj Mode")), self);
  349. self.sc2.activated.connect(self.tajmode)
  350. ## Spell checker toggle
  351. #self.sc3 = QtGui.QShortcut(QtGui.QKeySequence("Shift+Ctrl+Y"), self);
  352. #self.sc3.activated.connect(self.togglespell)
  353. # Action shortcuts
  354. self.sc4 = QtGui.QShortcut(QtGui.QKeySequence(self.tr("Ctrl+O","Open File")), self);
  355. self.sc4.activated.connect(self.editor.open)
  356. self.sc5 = QtGui.QShortcut(QtGui.QKeySequence(self.tr("Ctrl+S","Save File")), self);
  357. self.sc5.activated.connect(self.editor.save)
  358. self.sc6 = QtGui.QShortcut(QtGui.QKeySequence(self.tr("Shift+Ctrl+S","Save File As")), self);
  359. self.sc6.activated.connect(self.editor.saveas)
  360. self.sc7 = QtGui.QShortcut(QtGui.QKeySequence(self.tr("Ctrl+N","New File")), self);
  361. self.sc7.activated.connect(self.editor.new)
  362. self.sc8 = QtGui.QShortcut(QtGui.QKeySequence(self.tr("Ctrl+Q","Quit")), self);
  363. # Prefs
  364. self.sc9 = QtGui.QShortcut(QtGui.QKeySequence(self.tr("Shift+Ctrl+P","Show Preferences")), self);
  365. self.sc9.activated.connect(self.showprefs)
  366. # Document information
  367. self.sc10 = QtGui.QShortcut(QtGui.QKeySequence(self.tr("Ctrl+I","Show Document Info")), self);
  368. self.sc10.activated.connect(self.showinfo)
  369. # Help
  370. self.sc11 = QtGui.QShortcut(QtGui.QKeySequence(self.tr("F1","Help")), self);
  371. self.sc11.activated.connect(self.showhelp)
  372. # Dismiss bars
  373. self.sc12 = QtGui.QShortcut(QtGui.QKeySequence(self.tr("Esc")), self);
  374. self.sc12.activated.connect(self.hidewidgets)
  375. # Goto line
  376. self.sc13 = QtGui.QShortcut(QtGui.QKeySequence(self.tr("Ctrl+G")), self)
  377. self.sc13.activated.connect(self.showgotoline)
  378. self.editorBG=QtGui.QGraphicsRectItem()
  379. self.editorBG.setFlag(QtGui.QGraphicsItem.ItemIsMovable, True)
  380. self.editorBG.setCursor(QtCore.Qt.PointingHandCursor)
  381. self.editorBG.setBrush(QtGui.QColor(255,255,255))
  382. self.editorBG.setZValue(-999)
  383. self._scene.addItem(self.editorBG)
  384. self.handles=[]
  385. for h in range(0,4):
  386. h=Handle(0,0,10,10)
  387. h.setFlag(QtGui.QGraphicsItem.ItemIsMovable, True)
  388. h.setCursor(QtCore.Qt.SizeAllCursor)
  389. h.setZValue(100)
  390. self._scene.addItem(h)
  391. self.handles.append(h)
  392. self.fontButton=FunkyButton("fonts.svg", self.tr('Font'), self._scene)
  393. self.sizeButton=FunkyButton("size.svg", self.tr('Size'), self._scene)
  394. self.fileButton=FunkyButton("file.svg", self.tr('File'), self._scene)
  395. self.bgButton=FunkyButton("bg.svg", self.tr('Bg'), self._scene)
  396. if SOUND:
  397. self.clickButton=FunkyButton("click.svg", self.tr('Click'), self._scene)
  398. self.musicButton=FunkyButton("music.svg", self.tr('Music'), self._scene)
  399. self.configButton=FunkyButton("configure.svg", self.tr('Options'), self._scene)
  400. self.configButton.clicked.connect(self.showprefs)
  401. self.quitButton=FunkyButton("exit.svg", self.tr('Quit'), self._scene)
  402. self.quitButton.clicked.connect(self.close)
  403. self.sc8.activated.connect(self.quitButton.animateClick)
  404. self.buttons=[self.fontButton,
  405. self.sizeButton,
  406. self.fileButton,
  407. self.bgButton]
  408. if SOUND:
  409. self.buttons+=[self.clickButton,
  410. self.musicButton]
  411. self.buttons+=[self.configButton,
  412. self.quitButton]
  413. self.fontList=FunkyFontList(self._scene)
  414. self.fontList.currentFontChanged.connect(self.changefont)
  415. self.fontColor=FunkyButton("color.svg", self.tr('Color'), self._scene,"FontColor")
  416. self.fontColor.clicked.connect(self.setfontcolor)
  417. self.fontButton.children+=[self.fontList,self.fontColor]
  418. self.size1=FunkyButton("minus.svg", self.tr('Smaller'), self._scene)
  419. self.size2=FunkyButton("equals.svg", self.tr('Default'), self._scene)
  420. self.size3=FunkyButton("plus.svg", self.tr('Larger'), self._scene)
  421. self.size1.clicked.connect(self.editor.smaller)
  422. self.size3.clicked.connect(self.editor.larger)
  423. self.size2.clicked.connect(self.editor.default)
  424. self.sizeButton.children+=[self.size1, self.size2, self.size3]
  425. self.file1=FunkyButton("open.svg", self.tr('Open'), self._scene)
  426. self.file2=FunkyButton("save.svg", self.tr('Save'), self._scene)
  427. self.file3=FunkyButton("saveas.svg", self.tr('Save As'), self._scene, "SaveAs")
  428. self.file1.clicked.connect(self.editor.open)
  429. self.file2.clicked.connect(self.editor.save)
  430. self.file3.clicked.connect(self.editor.saveas)
  431. self.fileButton.children+=[self.file1, self.file2, self.file3]
  432. self.bg1=FunkyButton("previous.svg", self.tr('Previous'), self._scene, "PreviousBG")
  433. self.bg2=FunkyButton("next.svg", self.tr('Next'), self._scene,"NextBG")
  434. self.bg3=FunkyButton("color.svg", self.tr('Color'), self._scene,"ColorBG")
  435. self.bg1.clicked.connect(self.prevbg)
  436. self.bg2.clicked.connect(self.nextbg)
  437. self.bg3.clicked.connect(self.setbgcolor)
  438. self.bgButton.children+=[self.bg1, self.bg2, self.bg3]
  439. if SOUND:
  440. self.click1=FunkyButton("previous.svg", self.tr('Previous'), self._scene,"PreviousClick")
  441. self.click2=FunkyButton("next.svg", self.tr('Next'), self._scene,"NextClick")
  442. self.click3=FunkyButton("mute.svg", self.tr('None'), self._scene,"NoCLick")
  443. self.click1.clicked.connect(self.prevclick)
  444. self.click2.clicked.connect(self.nextclick)
  445. self.click3.clicked.connect(self.noclick)
  446. self.clickButton.children+=[self.click1, self.click2, self.click3]
  447. self.music1=FunkyButton("previous.svg", self.tr('Previous'), self._scene,"PreviousMusic")
  448. self.music2=FunkyButton("next.svg", self.tr('Next'), self._scene,"NextMusic")
  449. self.music3=FunkyButton("mute.svg", self.tr('None'), self._scene,"NoMusic")
  450. self.music1.clicked.connect(self.prevstation)
  451. self.music2.clicked.connect(self.nextstation)
  452. self.music3.clicked.connect(self.nostation)
  453. self.musicButton.children+=[self.music1, self.music2, self.music3]
  454. # Prefs widget
  455. self.prefsWidget=PrefsWidget(self._scene,mainwindow=self)
  456. self.prefsWidget.ui.close.clicked.connect(self.hidewidgets)
  457. self.prefsWidget.ui.saveTheme.clicked.connect(self.savetheme)
  458. self.prefsWidget.ui.themeList.currentIndexChanged.connect(self.loadtheme)
  459. self.prefsWidget.ui.styleList.currentIndexChanged.connect(self.loadstyle)
  460. self.prefsWidget.ui.buttonStyle.currentIndexChanged.connect(self.buttonstyle)
  461. self.prefsWidget.ui.langBox.currentIndexChanged.connect(self.setHL)
  462. self.prefsWidget.ui.opacity.valueChanged.connect(self.editoropacity)
  463. self.prefsWidget.ui.buttonStyle.setCurrentIndex(self.settings.value('buttonstyle').toInt()[0])
  464. self.prefsWidget.ui.autoSave.valueChanged.connect(self.setsavetimer)
  465. self.prefsWidget.ui.syntaxList.currentIndexChanged.connect(self.setHL)
  466. self.prefsWidget.ui.schemeList.currentIndexChanged.connect(self.setHL)
  467. self.prefsWidget.ui.syntax.toggled.connect(self.setHL)
  468. self.prefsWidget.ui.spelling.toggled.connect(self.setHL)
  469. self.saveTimer=QtCore.QTimer()
  470. self.saveTimer.timeout.connect(self.savebytimer)
  471. self.prefsWidget.ui.autoSave.setValue(self.settings.value('autosave').toInt()[0])
  472. # Goto Line widget
  473. self.gotoLineWidget=self.editor.gotoLineWidget()
  474. self.gotoLineWidget.proxy=self._scene.addWidget(self.gotoLineWidget)
  475. self.gotoLineWidget.proxy.setZValue(100)
  476. self.gotoLineWidget.proxy.setFlag(QtGui.QGraphicsItem.ItemIsMovable, False)
  477. self.gotoLineWidget.proxy.setOpacity(0)
  478. # Don't autohide it because we animate it
  479. self.gotoLineWidget.ui.close.clicked.disconnect(self.gotoLineWidget.hide)
  480. self.gotoLineWidget.ui.close.clicked.connect(self.hidewidgets)
  481. # Search widget
  482. self.searchWidget=self.editor.searchWidget()
  483. self.searchWidget.proxy=self._scene.addWidget(self.searchWidget)
  484. self.searchWidget.proxy.setZValue(100)
  485. self.searchWidget.proxy.setFlag(QtGui.QGraphicsItem.ItemIsMovable, False)
  486. self.searchWidget.proxy.setOpacity(0)
  487. # Don't autohide it because we animate it
  488. self.searchWidget.ui.close.clicked.disconnect(self.searchWidget.hide)
  489. self.searchWidget.ui.close.clicked.connect(self.hidewidgets)
  490. # Search and replace widget
  491. self.searchReplaceWidget=self.editor.searchReplaceWidget()
  492. self.searchReplaceWidget.hide()
  493. self.searchReplaceWidget.proxy=self._scene.addWidget(self.searchReplaceWidget)
  494. self.searchWidget.proxy.setZValue(100)
  495. self.searchWidget.proxy.setFlag(QtGui.QGraphicsItem.ItemIsMovable, False)
  496. self.searchWidget.proxy.setOpacity(0)
  497. self.searchReplaceWidget.ui.close.clicked.disconnect(self.searchReplaceWidget.hide)
  498. self.searchReplaceWidget.ui.close.clicked.connect(self.hidewidgets)
  499. def editorLangChanged(self, lang):
  500. lang=unicode(lang).split('.')[0]
  501. idx=self.prefsWidget.ui.syntaxList.findText(lang)
  502. self.prefsWidget.ui.syntax.setChecked(True)
  503. self.prefsWidget.ui.syntaxList.currentIndexChanged.disconnect(self.setHL)
  504. self.prefsWidget.ui.syntaxList.setCurrentIndex(idx)
  505. self.prefsWidget.ui.syntaxList.currentIndexChanged.connect(self.setHL)
  506. def setHL(self, idx):
  507. # Ignore args, take the data from prefsWidget
  508. if self.prefsWidget.ui.spelling.isChecked():
  509. # Enable spellchecking
  510. l=unicode(self.prefsWidget.ui.langBox.currentText())
  511. self.setspellchecker(l)
  512. self.settings.setValue('lang',l)
  513. elif srchiliteqt:
  514. # Enable syntax highlighting
  515. l=self.prefsWidget._l
  516. lang='lang-'+unicode(self.prefsWidget.ui.syntaxList.currentText())
  517. scheme='scheme-'+unicode(self.prefsWidget.ui.schemeList.currentText())
  518. self.settings.setValue('scheme', self.prefsWidget.ui.schemeList.currentText())
  519. self.editor.setHL(l[lang], l[scheme])
  520. self.settings.setValue('lang',QtCore.QVariant())
  521. self.settings.sync()
  522. def setsavetimer(self, value=None):
  523. if value is None:
  524. return
  525. self.settings.setValue('autosave', value)
  526. self.settings.sync()
  527. if value:
  528. self.notify(self.tr('Saving every %n minutes','',value))
  529. self.saveTimer.setInterval(60*1000*value)
  530. self.saveTimer.start()
  531. else:
  532. self.notify(self.tr('Disabled automatic saving'))
  533. self.saveTimer.stop()
  534. def savebytimer(self):
  535. try:
  536. if self.editor.docName: # No autosaving UNNAMED
  537. self.editor.save()
  538. except:
  539. pass
  540. self.setsavetimer()
  541. def warnnosound(self):
  542. self.notify(unicode(self.tr('Sound support is not available, disabling sound')))
  543. def showhelp(self):
  544. QtGui.QDesktopServices.openUrl(QtCore.QUrl('file://'+PATH+'/README.html'))
  545. def showinfo(self):
  546. txt=unicode(self.editor.toPlainText())
  547. lc=len(txt.splitlines())
  548. wc=len(re.split('[\n\t ]',txt))
  549. name=os.path.basename(self.editor.docName) or "UNNAMED"
  550. s1=unicode(self.tr('Document: %s'))%name
  551. s2=unicode(self.tr('%n words','',wc))
  552. s3=unicode(self.tr('%n lines','',lc))
  553. s4=unicode(self.tr('%n characters','',len(txt)))
  554. self.notify(s1+u' -- '+s2+u' -- '+s3+u' -- '+s4)
  555. def notifChanged(self, msg):
  556. if unicode(msg):
  557. fadein(self.notifBar)
  558. else:
  559. fadeout(self.notifBar)
  560. def notify(self, text):
  561. self.notifBar.showMessage(text, 3000)
  562. def layoutButtons(self):
  563. mmLayout=QtGui.QGraphicsGridLayout()
  564. mmLayout.setContentsMargins(self.m * 3,0,0,0)
  565. for r, b in enumerate(self.buttons):
  566. if not b.isVisible(): continue
  567. b.submenu=QtGui.QGraphicsWidget()
  568. self._scene.addItem(b.submenu)
  569. b.submenu.setLayout(QtGui.QGraphicsLinearLayout())
  570. b.submenu.layout().setContentsMargins(0,0,0,0)
  571. mmLayout.addItem(b.proxy,r,0,1,1,
  572. QtCore.Qt.AlignVCenter|QtCore.Qt.AlignCenter)
  573. for c in b.children:
  574. b.submenu.layout().addItem(c.proxy)
  575. b.submenu.layout().addStretch()
  576. mmLayout.addItem(b.submenu,r,1,1,1,
  577. QtCore.Qt.AlignVCenter|QtCore.Qt.AlignCenter)
  578. mmLayout.setRowFixedHeight(r, b.height())
  579. mmLayout.setRowSpacing(r, self.m)
  580. self.mainMenu=MenuStrip(self._scene)
  581. self.mainMenu.proxy.setLayout(mmLayout)
  582. self.mainMenu.setPos(self.editorX+self.editorW+20,self.editorY)
  583. self.container=QtGui.QGraphicsWidget()
  584. self._scene.addItem(self.container)
  585. self.containerLayout=QtGui.QGraphicsLinearLayout()
  586. self.containerLayout.setContentsMargins(0,0,0,0)
  587. if self.editor.canvaseditor:
  588. self.containerLayout.addItem(self.editor.proxy)
  589. self.containerLayout.addItem(self.mainMenu)
  590. self.container.setLayout(self.containerLayout)
  591. def editoropacity(self, v):
  592. self.notify(unicode(self.tr("Setting opacity to: %s%%"))%v)
  593. fadein(self.editorBG, target=v/100.)
  594. self.settings.setValue("editoropacity",v)
  595. self.settings.sync()
  596. def buttonstyle(self, idx):
  597. self.buttonStyle=idx
  598. self.settings.setValue('buttonstyle',self.buttonStyle)
  599. self.settings.sync()
  600. for b in buttons:
  601. if idx==0:
  602. b.setIcon(QtGui.QIcon(os.path.join(PATH,'icons',b.icon)))
  603. b.setText("")
  604. elif idx==1:
  605. b.setIcon(QtGui.QIcon())
  606. b.setText(b.text)
  607. elif idx==2:
  608. b.setIcon(QtGui.QIcon(os.path.join(PATH,'icons',b.icon)))
  609. b.setText(b.text)
  610. self.layoutButtons()
  611. def loadstyle(self, styleidx):
  612. stylename=unicode(self.prefsWidget.ui.styleList.itemText(styleidx))
  613. stylefile=os.path.join(PATH,'stylesheets',stylename)
  614. self.notify (unicode(self.tr('Changing to style %s requires restarting Marave'))%stylename)
  615. self.settings.setValue('style',stylename)
  616. self.settings.sync()
  617. def loadtheme(self, themeidx):
  618. if not themeidx:
  619. return
  620. themename=unicode(self.prefsWidget.ui.themeList.itemText(themeidx))
  621. themefile=os.path.join(PATH,'themes',themename)
  622. self.oldSettings=self.settings
  623. self.settings=QtCore.QSettings(themefile,QtCore.QSettings.IniFormat)
  624. #self.loadprefs()
  625. self.loadBG()
  626. self.loadOpacity()
  627. self.loadFont()
  628. self.settings=self.oldSettings
  629. self.saveprefs()
  630. def savetheme(self, themefile=None):
  631. #from pudb import set_trace; set_trace()
  632. try:
  633. self.prefsWidget.ui.themeList.currentIndexChanged.disconnect()
  634. except TypeError:
  635. pass
  636. if themefile is None or themefile is False:
  637. tdir=os.path.join(PATH,'themes')
  638. fdialog = QtGui.QFileDialog(self, self.tr("Save Theme"), tdir)
  639. fdialog.setFileMode(fdialog.AnyFile)
  640. fdialog.setAcceptMode(fdialog.AcceptSave)
  641. fname = None
  642. if fdialog.exec_():
  643. fname = unicode(fdialog.selectedFiles()[0])
  644. self.savetheme(fname)
  645. return
  646. self.oldSettings=self.settings
  647. self.settings=QtCore.QSettings(QtCore.QString(themefile),QtCore.QSettings.IniFormat)
  648. self.saveprefs()
  649. # Don't save the size and position of the editor in the theme
  650. self.settings.remove('x')
  651. self.settings.remove('y')
  652. self.settings.remove('w')
  653. self.settings.remove('h')
  654. self.settings.sync()
  655. self.settings=self.oldSettings
  656. self.prefsWidget.loadthemelist()
  657. self.prefsWidget.ui.themeList.currentIndexChanged.connect(self.loadtheme)
  658. def saveprefs(self):
  659. # Save all settings at once
  660. self.settings.setValue('font',self.editor.font())
  661. self.settings.setValue('fontsize',self.editor.font().pointSize())
  662. if self.currentClick:
  663. self.settings.setValue('click',self.currentClick)
  664. else:
  665. self.settings.setValue('click',QtCore.QVariant())
  666. if self.currentStation:
  667. self.settings.setValue('station',self.currentStation)
  668. else:
  669. self.settings.setValue('station',QtCore.QVariant())
  670. if self.bgcolor:
  671. self.settings.setValue('bgcolor',self.bgcolor.name())
  672. self.settings.setValue('background',QtCore.QVariant())
  673. else:
  674. self.settings.setValue('bgcolor',QtCore.QVariant())
  675. self.settings.setValue('background',self.currentBG)
  676. if self.fontcolor:
  677. self.settings.setValue('fontcolor',self.fontcolor.name())
  678. self.saveEditorGeometry()
  679. self.settings.setValue('buttonstyle',self.buttonStyle)
  680. self.settings.setValue('editoropacity', self.editorBG.opacity()*100)
  681. self.settings.setValue('autosave', self.prefsWidget.ui.autoSave.value())
  682. self.settings.sync()
  683. def saveEditorGeometry(self):
  684. if self.hasSize:
  685. self.settings.setValue('x',int(self.editorX))
  686. self.settings.setValue('y',int(self.editorY))
  687. self.settings.setValue('w',int(self.editorW))
  688. self.settings.setValue('h',int(self.editorH))
  689. self.settings.sync()
  690. def loadBG(self):
  691. "Load background from the preferences"
  692. bgcolor=self.settings.value('bgcolor')
  693. bg=self.settings.value('background')
  694. if not bg.isValid() and not bgcolor.isValid():
  695. # Probably first run
  696. self.nextbg()
  697. elif bg.isValid():
  698. self.setbg(unicode(bg.toString()))
  699. elif bgcolor.isValid():
  700. self.setbgcolor(QtGui.QColor(bgcolor.toString()))
  701. def loadSound(self):
  702. "Load sound settings from config file"
  703. c=self.settings.value('click')
  704. if c.isValid():
  705. self.setclick(unicode(c.toString()))
  706. else:
  707. self.noclick()
  708. s=self.settings.value('station')
  709. if s.isValid():
  710. self.setstation(unicode(s.toString()))
  711. else:
  712. self.nostation()
  713. def loadGeometry(self):
  714. x=self.settings.value('x')
  715. y=self.settings.value('y')
  716. w=self.settings.value('w')
  717. h=self.settings.value('h')
  718. if x.isValid() and y.isValid() and w.isValid() and h.isValid():
  719. self.hasSize=True
  720. self.editorX=x.toInt()[0]
  721. self.editorY=y.toInt()[0]
  722. self.editorW=max(w.toInt()[0], self.minW)
  723. self.editorH=max(h.toInt()[0], self.minH)
  724. self.adjustPositions()
  725. def loadFont(self):
  726. f=QtGui.QFont()
  727. fname=self.settings.value('font')
  728. if fname.isValid():
  729. f.fromString(fname.toString())
  730. else:
  731. f.setFamily('courier')
  732. fs,ok=self.settings.value('fontsize').toInt()
  733. if ok:
  734. f.setPointSize(fs)
  735. self.editor.setFont(f)
  736. self.fontList.setCurrentFont(f)
  737. fontcolor=self.settings.value('fontcolor')
  738. if fontcolor.isValid():
  739. self.setfontcolor(QtGui.QColor(fontcolor.toString()))
  740. else:
  741. self.setfontcolor(QtGui.QColor('black'))
  742. def loadOpacity(self):
  743. o,ok=self.settings.value('editoropacity').toInt()
  744. if ok:
  745. self.editorBG.setOpacity( o/100.)
  746. else:
  747. self.editorBG.setOpacity( .1)
  748. def loadprefs(self):
  749. # Load all settings
  750. if len(self.settings.allKeys()) == 0:
  751. # First run
  752. self.loadtheme(1)
  753. self.loadGeometry()
  754. self.loadFont()
  755. self.loadOpacity()
  756. bs,ok=self.settings.value('buttonstyle').toInt()
  757. if ok:
  758. self.buttonStyle=bs
  759. else:
  760. self.buttonStyle=0
  761. self.buttonstyle(self.buttonStyle)
  762. self.loadBG()
  763. l=self.settings.value('lang')
  764. if l.isValid():
  765. self.setspellchecker(unicode(l.toString()))
  766. else:
  767. self.setspellchecker('None')
  768. style=self.settings.value('style')
  769. if style.isValid():
  770. style=unicode(style.toString())
  771. else:
  772. style='default'
  773. self.prefsWidget.ui.styleList.setCurrentIndex(self.prefsWidget.ui.styleList.findText(style))
  774. QtCore.QCoreApplication.instance().setStyleSheet(open(os.path.join(PATH,'stylesheets',style)).read())
  775. # Color scheme for syntax highlighter
  776. scheme=self.settings.value('scheme')
  777. if scheme.isValid():
  778. scheme=unicode(scheme.toString())
  779. else:
  780. scheme='default'
  781. self.prefsWidget.ui.schemeList.setCurrentIndex(self.prefsWidget.ui.schemeList.findText(scheme))
  782. QtCore.QTimer.singleShot(10,self.loadSound)
  783. def setspellchecker(self, code):
  784. if isinstance (code, int):
  785. code=unicode(self.prefsWidget.ui.langBox.itemText(code))
  786. if "dict" not in self.editor.__dict__:
  787. # No pyenchant
  788. return
  789. if code == 'None':
  790. self.lang=None
  791. self.editor.killDict()
  792. self.prefsWidget.ui.langBox.setCurrentIndex(0)
  793. else:
  794. self.lang=code
  795. self.editor.initDict(self.lang)
  796. self.prefsWidget.ui.langBox.setCurrentIndex(self.prefsWidget.ui.langBox.findText(self.lang))
  797. if self.prefsWidget.ui.spelling.isChecked():
  798. self.settings.setValue('lang',self.lang)
  799. else:
  800. self.settings.setValue('lang',QtCore.QVariant())
  801. self.settings.sync()
  802. def close(self):
  803. QtCore.QCoreApplication.instance().setOverrideCursor(QtCore.Qt.ArrowCursor)
  804. if self.editor.document().isModified():
  805. r=QtGui.QMessageBox.question(self, self.tr("Close Document - Marave"),
  806. unicode(self.tr("The document \"%s\" has been modified."))%(self.editor.docName or self.tr("UNNAMED"))+
  807. self.tr("\nDo you want to save your changes or discard them?"),
  808. QtGui.QMessageBox.Save|QtGui.QMessageBox.Discard|QtGui.QMessageBox.Cancel,QtGui.QMessageBox.Cancel)
  809. if r==QtGui.QMessageBox.Save:
  810. self.editor.save()
  811. elif r==QtGui.QMessageBox.Discard:
  812. self.saveprefs()
  813. QtGui.QGraphicsView.close(self)
  814. if self.beep:
  815. self.beep.stop()
  816. for path in self.beep.outputPaths():
  817. path.disconnect()
  818. if self.music:
  819. self.music.stop()
  820. for path in self.music.outputPaths():
  821. path.disconnect()
  822. QtCore.QCoreApplication.instance().quit()
  823. else:
  824. self.saveprefs()
  825. QtGui.QGraphicsView.close(self)
  826. if self.beep:
  827. self.beep.stop()
  828. for path in self.beep.outputPaths():
  829. path.disconnect()
  830. if self.music:
  831. self.music.stop()
  832. for path in self.music.outputPaths():
  833. path.disconnect()
  834. QtCore.QCoreApplication.instance().quit()
  835. QtCore.QCoreApplication.instance().restoreOverrideCursor()
  836. def showbar(self, w):
  837. self.hidewidgets()
  838. self.visibleWidget=w
  839. w.show()
  840. def later():
  841. self.editor.autoResize=True
  842. fadein(w)
  843. self.editor.autoResize=False
  844. animheight(self.editor,self.editorH-w.height(), thendo=later)
  845. self.setFocus()
  846. def showsearchreplace(self):
  847. self.showbar(self.searchReplaceWidget)
  848. self.setFocus()
  849. self.searchReplaceWidget.ui.text.setFocus()
  850. def showsearch(self):
  851. self.showbar(self.searchWidget)
  852. self.setFocus()
  853. self.searchWidget.ui.text.setFocus()
  854. def showprefs(self):
  855. self.prefsWidget.ui.opacity.setValue(self.editorBG.opacity()*100)
  856. self.showbar(self.prefsWidget)
  857. def showgotoline(self):
  858. self.showbar(self.gotoLineWidget)
  859. self.setFocus()
  860. self.gotoLineWidget.ui.line.setFocus()
  861. def hidewidgets(self):
  862. def later():
  863. self.editor.resize(self.editorW,self.editorH)
  864. self.editor.autoResize=True
  865. self.editor.setFocus()
  866. self.editor.autoResize=False
  867. for w in [self.searchWidget,
  868. self.searchReplaceWidget,
  869. self.gotoLineWidget,
  870. self.prefsWidget
  871. ]:
  872. fadeout(w)
  873. # This one is separate because it triggers
  874. # resizing the editor
  875. QtCore.QTimer.singleShot(200,later)
  876. self.visibleWidget=None
  877. def rewind(self):
  878. if self.beep:
  879. self.beep.seek(0)
  880. def setclick(self, clickname):
  881. if not SOUND: return
  882. self.currentClick=clickname
  883. self.notify(unicode(self.tr('Switching click to: %s'))%self.currentClick)
  884. self.beep = Phonon.createPlayer(Phonon.NotificationCategory,
  885. Phonon.MediaSource(os.path.join(PATH,'clicks',self.currentClick)))
  886. self.beep.finished.connect( self.rewind )
  887. self.beep.play()
  888. self.settings.setValue('click',self.currentClick)
  889. self.settings.sync()
  890. def prevclick(self):
  891. clist=os.listdir(os.path.join(PATH,'clicks'))
  892. clist=[x for x in clist if not x.startswith('.')]
  893. clist.sort()
  894. try:
  895. idx=(clist.index(self.currentClick)-1)%len(clist)
  896. except ValueError:
  897. idx=-1
  898. self.setclick(clist[idx])
  899. def nextclick(self):
  900. clist=os.listdir(os.path.join(PATH,'clicks'))
  901. clist=[x for x in clist if not x.startswith('.')]
  902. clist.sort()
  903. try:
  904. idx=(clist.index(self.currentClick)+1)%len(clist)
  905. except ValueError:
  906. idx=-1
  907. self.setclick(clist[idx])
  908. def noclick(self):
  909. self.notify(unicode(self.tr('Disabling click')))
  910. self.beep=None
  911. self.currentClick=None
  912. def audiometadatachanged(self):
  913. try:
  914. self.notify (unicode(self.tr('Listening to: %s'))%self.music.metaData('TITLE')[0])
  915. except:
  916. pass
  917. def setstation(self, station):
  918. if not SOUND: return
  919. self.currentStation=station
  920. if self.music:
  921. self.music.deleteLater()
  922. self.music = Phonon.createPlayer(Phonon.MusicCategory,
  923. Phonon.MediaSource(self.currentStation))
  924. self.music.metaDataChanged.connect(self.audiometadatachanged)
  925. self.music.play()
  926. self.settings.setValue('station',self.currentStation)
  927. self.settings.sync()
  928. def prevstation(self):
  929. try:
  930. idx=(self.stations.index(self.currentStation)-1)%len(self.stations)
  931. except ValueError:
  932. idx=-1
  933. self.setstation(self.stations[idx])
  934. def nextstation(self):
  935. try:
  936. idx=(self.stations.index(self.currentStation)+1)%len(self.stations)
  937. except ValueError:
  938. idx=-1
  939. self.setstation(self.stations[idx])
  940. def nostation(self):
  941. if self.music:
  942. self.music.stop()
  943. self.notify(unicode(self.tr('Disabling music')))
  944. self.currentStation=None
  945. def setbg(self, bg):
  946. #from pudb import set_trace; set_trace()
  947. if bg != self.currentBG:
  948. self.currentBG=bg
  949. self.bgcolor=None
  950. self.notify(unicode(self.tr('Setting background to: %s'))%self.currentBG)
  951. if self.currentBG.split('.')[-1] in ["svg","svgz"]:
  952. # Render the SVG to a QImage
  953. renderer=QtSvg.QSvgRenderer(os.path.join(PATH,'backgrounds',bg))
  954. w,h=renderer.defaultSize().width(), renderer.defaultSize().height()
  955. while w < self.width() or \
  956. h < self.height():
  957. w *=1.2
  958. h *=1.2
  959. self.bg=QtGui.QImage(w,h,QtGui.QImage.Format_ARGB32_Premultiplied)
  960. painter=QtGui.QPainter(self.bg)
  961. renderer.render(painter)
  962. painter.end()
  963. #self.bg=QtGui.QImage(pm)
  964. else:
  965. self.bg=QtGui.QImage(os.path.join(PATH,'backgrounds',bg))
  966. self.realBg=self.bg.scaled( self.size(), QtCore.Qt.KeepAspectRatioByExpanding, QtCore.Qt.SmoothTransformation)
  967. self.bgItem.setPixmap(QtGui.QPixmap(self.realBg))
  968. self.bgItem.setPos(self.width()-self.realBg.width(), self.height()-self.realBg.height())
  969. def prevbg(self):
  970. bglist=os.listdir(os.path.join(PATH,'backgrounds'))
  971. bglist=[x for x in bglist if not x.startswith('.')]
  972. bglist.sort()
  973. try:
  974. idx=(bglist.index(self.currentBG)-1)%len(bglist)
  975. except ValueError:
  976. idx=-1
  977. self.setbg(bglist[idx])
  978. def nextbg(self):
  979. bglist=os.listdir(os.path.join(PATH,'backgrounds'))
  980. bglist=[x for x in bglist if not x.startswith('.')]
  981. bglist.sort()
  982. try:
  983. idx=(bglist.index(self.currentBG)+1)%len(bglist)
  984. except ValueError:
  985. idx=0
  986. self.setbg(bglist[idx])
  987. def setbgcolor(self, bgcolor=None):
  988. if isinstance(bgcolor, QtGui.QColor):
  989. if bgcolor.isValid():
  990. self.bg=None
  991. self.realBG=None
  992. self.bgcolor=bgcolor
  993. pm=QtGui.QPixmap(self.width(), self.height())
  994. pm.fill(bgcolor)
  995. self.bgItem.setPixmap(pm)
  996. self.bgItem.setPos(0,0)
  997. self.notify(unicode(self.tr('Setting background to: %s'))%bgcolor.name())
  998. else:
  999. if self.bgcolor:
  1000. self.setbgcolor(QtGui.QColorDialog.getColor(self.bgcolor, self))
  1001. else:
  1002. self.setbgcolor(QtGui.QColorDialog.getColor(QtGui.QColor("white"), self))
  1003. def setfontcolor(self, color=None):
  1004. if isinstance(color, QtGui.QColor):
  1005. if color.isValid():
  1006. self.editor.setStyleSheet("""background-color: transparent;
  1007. color: %s;
  1008. """%(unicode(color.name())))
  1009. self.settings.setValue('fontcolor',color.name())
  1010. self.fontcolor=color
  1011. self.settings.sync()
  1012. else:
  1013. self.setfontcolor(QtGui.QColorDialog.getColor(QtGui.QColor("black"), self))
  1014. def tajmode(self):
  1015. self.noclick()
  1016. self.nostation()
  1017. self.setbgcolor(QtGui.QColor(0,0,0))
  1018. self.setfontcolor(QtGui.QColor(0,255,0))
  1019. def eventFilter(self, obj, event):
  1020. if obj==self.editor:
  1021. if event.type()==QtCore.QEvent.KeyPress:
  1022. if self.beep:
  1023. #if self.beep.state()==2:
  1024. self.beep.stop()
  1025. self.beep.seek(0)
  1026. self.beep.play()
  1027. self.hideCursor()
  1028. if not self.buttonsHidden:
  1029. self.hideButtons()
  1030. elif isinstance(event, QtGui.QMoveEvent):
  1031. self.showCursor()
  1032. self.showButtons()
  1033. elif isinstance(event, QtGui.QHoverEvent):
  1034. for b in self.buttons:
  1035. if b != obj:
  1036. b.hideChildren()
  1037. else:
  1038. b.showChildren()
  1039. self.showButtons()
  1040. return QtGui.QGraphicsView.eventFilter(self, obj, event)
  1041. def keyEvent(self, ev):
  1042. self.hideCursor()
  1043. def mouseMoveEvent(self, ev):
  1044. self.showCursor()
  1045. self.showButtons()
  1046. QtGui.QGraphicsView.mouseMoveEvent(self, ev)
  1047. def changefont(self, font):
  1048. f=self.editor.font()
  1049. f.setFamily(font.family())
  1050. self.editor.setFont(f)
  1051. self.settings.setValue('font',self.editor.font())
  1052. self.settings.sync()
  1053. def resizeEvent(self, ev):
  1054. self._scene.setSceneRect(QtCore.QRectF(self.geometry()))
  1055. if self.bg:
  1056. self.setbg(self.currentBG)
  1057. elif self.bgcolor:
  1058. self.setbgcolor(self.bgcolor)
  1059. if not self.hasSize:
  1060. self.editorX=self.width()*.1
  1061. self.editorH=max(self.height()*.9, self.minH)
  1062. self.editorY=self.height()*.05
  1063. self.editorW=max(self.width()*.6, self.minW)
  1064. self.adjustPositions()
  1065. def adjustPositions(self):
  1066. m=self.m
  1067. #self.changing=False
  1068. menuW=self.mainMenu.geometry().width()
  1069. if self.isLeftToRight():
  1070. leftD=0
  1071. else:
  1072. leftD=menuW
  1073. if self.editor:
  1074. if self.editor.autoResize:
  1075. # This is when using in-canvas editor
  1076. if self.editor.canvaseditor:
  1077. self.container.setGeometry(self.editorX-leftD,self.editorY,
  1078. self.editorW+menuW, self.editorH)
  1079. else:
  1080. if self.isLeftToRight():
  1081. self.container.setGeometry(self.editorX+self.editorW+m,
  1082. self.editorY, menuW, self.editorH)
  1083. else: #not canvaseditor, and menu on the left
  1084. self.container.setGeometry(self.editorX-menuW,
  1085. self.editorY, menuW, self.editorH)
  1086. self.editor.move(self.editorX, self.editorY)
  1087. if self.visibleWidget:
  1088. self.editor.resize(self.editorW,self.editorH-self.visibleWidget.geometry().height()-2*self.m)
  1089. else:
  1090. self.editor.resize(self.editorW,self.editorH)
  1091. self.editorBG.setPos(self.editorX-m,self.editorY-m)
  1092. # Commenting this fixes Isue 15?????
  1093. #self.editorBG.setBrush(QtGui.QColor(255,255,255,255))
  1094. self.editorBG.setRect(0,0,self.editorW+2*m,self.editorH+2*m)
  1095. for w in (self.searchWidget,
  1096. self.searchReplaceWidget,
  1097. self.prefsWidget,
  1098. self.gotoLineWidget,
  1099. self.notifBar):
  1100. w.proxy.setPos(self.editorX,self.editorY+self.editorH-w.height())
  1101. w.setFixedWidth(self.editor.width())
  1102. self.notifBar.proxy.setPos(self.editorX,self.editorY+self.editorH+2*m)
  1103. self.handles[0].setPos(self.editorX-2*m,self.editorY-2*m)
  1104. self.handles[1].setPos(self.editorX+self.editorW,self.editorY-2*m)
  1105. self.handles[2].setPos(self.editorX+self.editorW,self.editorY+self.editorH)
  1106. self.handles[3].setPos(self.editorX-2*m,self.editorY+self.editorH)
  1107. self.saveEditorGeometry()
  1108. #self.changing=True
  1109. def scenechanged(self,region):
  1110. if not self.changing:
  1111. self.chan

Large files files are truncated, but you can click here to view the full file