diff --git a/scripts/qcookboob b/scripts/qcookboob
new file mode 100755
index 00000000..617f9d09
--- /dev/null
+++ b/scripts/qcookboob
@@ -0,0 +1,27 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+# vim: ft=python et softtabstop=4 cinoptions=4 shiftwidth=4 ts=4 ai
+
+# Copyright(C) 2013 Julien Veyssier
+#
+# This file is part of weboob.
+#
+# weboob is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# weboob is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with weboob. If not, see .
+
+
+from weboob.applications.qcookboob import QCookboob
+
+
+if __name__ == '__main__':
+ QCookboob.run()
diff --git a/weboob/applications/qcookboob/__init__.py b/weboob/applications/qcookboob/__init__.py
new file mode 100644
index 00000000..18938a1b
--- /dev/null
+++ b/weboob/applications/qcookboob/__init__.py
@@ -0,0 +1,3 @@
+from .qcookboob import QCookboob
+
+__all__ = ['QCookboob']
diff --git a/weboob/applications/qcookboob/main_window.py b/weboob/applications/qcookboob/main_window.py
new file mode 100644
index 00000000..7b8832b8
--- /dev/null
+++ b/weboob/applications/qcookboob/main_window.py
@@ -0,0 +1,199 @@
+# -*- coding: utf-8 -*-
+
+# Copyright(C) 2013 Julien Veyssier
+#
+# This file is part of weboob.
+#
+# weboob is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# weboob is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with weboob. If not, see .
+
+import os
+import codecs
+
+from PyQt4.QtCore import SIGNAL, Qt, QStringList
+from PyQt4.QtGui import QApplication, QCompleter
+
+from weboob.capabilities.recipe import ICapRecipe
+from weboob.tools.application.qt import QtMainWindow, QtDo
+from weboob.tools.application.qt.backendcfg import BackendCfg
+
+from weboob.applications.qcookboob.ui.main_window_ui import Ui_MainWindow
+
+from .minirecipe import MiniRecipe
+from .recipe import Recipe
+
+
+class MainWindow(QtMainWindow):
+ def __init__(self, config, weboob, parent=None):
+ QtMainWindow.__init__(self, parent)
+ self.ui = Ui_MainWindow()
+ self.ui.setupUi(self)
+
+ self.config = config
+ self.weboob = weboob
+ self.minis = []
+ self.current_info_widget = None
+
+ # search history is a list of patterns which have been searched
+ self.search_history = self.loadSearchHistory()
+ self.updateCompletion()
+
+ # action history is composed by the last action and the action list
+ # An action is a function, a list of arguments and a description string
+ self.action_history = {'last_action': None, 'action_list': []}
+ self.connect(self.ui.backButton, SIGNAL("clicked()"), self.doBack)
+ self.ui.backButton.hide()
+
+ self.connect(self.ui.searchEdit, SIGNAL("returnPressed()"), self.search)
+
+ self.connect(self.ui.actionBackends, SIGNAL("triggered()"), self.backendsConfig)
+ self.connect(self.ui.actionQuit, SIGNAL("triggered()"), self.close)
+
+ self.loadBackendsList()
+
+ if self.ui.backendEdit.count() == 0:
+ self.backendsConfig()
+
+ def backendsConfig(self):
+ bckndcfg = BackendCfg(self.weboob, (ICapRecipe, ), self)
+ if bckndcfg.run():
+ self.loadBackendsList()
+
+ def loadBackendsList(self):
+ self.ui.backendEdit.clear()
+ for i, backend in enumerate(self.weboob.iter_backends()):
+ if i == 0:
+ self.ui.backendEdit.addItem('All backends', '')
+ self.ui.backendEdit.addItem(backend.name, backend.name)
+ if backend.name == self.config.get('settings', 'backend'):
+ self.ui.backendEdit.setCurrentIndex(i+1)
+
+ if self.ui.backendEdit.count() == 0:
+ self.ui.searchEdit.setEnabled(False)
+ else:
+ self.ui.searchEdit.setEnabled(True)
+
+ def loadSearchHistory(self):
+ ''' Return search string history list loaded from history file
+ '''
+ result = []
+ history_path = os.path.join(self.weboob.workdir, 'qcookboob_history')
+ if os.path.exists(history_path):
+ f = codecs.open(history_path, 'r', 'utf-8')
+ conf_hist = f.read()
+ f.close()
+ if conf_hist is not None and conf_hist.strip() != '':
+ result = conf_hist.strip().split('\n')
+ return result
+
+ def saveSearchHistory(self):
+ ''' Save search history in history file
+ '''
+ if len(self.search_history) > 0:
+ history_path = os.path.join(self.weboob.workdir, 'qcookboob_history')
+ f = codecs.open(history_path, 'w', 'utf-8')
+ f.write('\n'.join(self.search_history))
+ f.close()
+
+ def updateCompletion(self):
+ qc = QCompleter(QStringList(self.search_history), self)
+ qc.setCaseSensitivity(Qt.CaseInsensitive)
+ self.ui.searchEdit.setCompleter(qc)
+
+ def doAction(self, description, fun, args):
+ ''' Call fun with args as arguments
+ and save it in the action history
+ '''
+ self.ui.currentActionLabel.setText(description)
+ if self.action_history['last_action'] is not None:
+ self.action_history['action_list'].append(self.action_history['last_action'])
+ self.ui.backButton.setToolTip(self.action_history['last_action']['description'])
+ self.ui.backButton.show()
+ self.action_history['last_action'] = {'function': fun, 'args': args, 'description': description}
+ return fun(*args)
+
+ def doBack(self):
+ ''' Go back in action history
+ Basically call previous function and update history
+ '''
+ if len(self.action_history['action_list']) > 0:
+ todo = self.action_history['action_list'].pop()
+ self.ui.currentActionLabel.setText(todo['description'])
+ self.action_history['last_action'] = todo
+ if len(self.action_history['action_list']) == 0:
+ self.ui.backButton.hide()
+ else:
+ self.ui.backButton.setToolTip(self.action_history['action_list'][-1]['description'])
+ return todo['function'](*todo['args'])
+
+ def search(self):
+ pattern = unicode(self.ui.searchEdit.text())
+ # arbitrary max number of completion word
+ if len(self.search_history) > 50:
+ self.search_history.pop(0)
+ if pattern not in self.search_history:
+ self.search_history.append(pattern)
+ self.updateCompletion()
+
+ self.searchRecipe()
+
+ def searchRecipe(self):
+ pattern = unicode(self.ui.searchEdit.text())
+ if not pattern:
+ return
+ self.doAction(u'Search recipe "%s"' % pattern, self.searchRecipeAction, [pattern])
+
+ def searchRecipeAction(self, pattern):
+ self.ui.stackedWidget.setCurrentWidget(self.ui.list_page)
+ for mini in self.minis:
+ self.ui.list_content.layout().removeWidget(mini)
+ mini.hide()
+ mini.deleteLater()
+
+ self.minis = []
+ self.ui.searchEdit.setEnabled(False)
+ QApplication.setOverrideCursor(Qt.WaitCursor)
+
+ backend_name = str(self.ui.backendEdit.itemData(self.ui.backendEdit.currentIndex()).toString())
+
+ self.process = QtDo(self.weboob, self.addRecipe)
+ self.process.do('iter_recipes', pattern, backends=backend_name, caps=ICapRecipe)
+
+ def addRecipe(self, backend, recipe):
+ if not backend:
+ self.ui.searchEdit.setEnabled(True)
+ QApplication.restoreOverrideCursor()
+ self.process = None
+ return
+ minirecipe = MiniRecipe(self.weboob, backend, recipe, self)
+ self.ui.list_content.layout().addWidget(minirecipe)
+ self.minis.append(minirecipe)
+
+ def displayRecipe(self, recipe, backend):
+ self.ui.stackedWidget.setCurrentWidget(self.ui.info_page)
+ if self.current_info_widget is not None:
+ self.ui.info_content.layout().removeWidget(self.current_info_widget)
+ self.current_info_widget.hide()
+ self.current_info_widget.deleteLater()
+ wrecipe = Recipe(recipe, backend, self)
+ self.ui.info_content.layout().addWidget(wrecipe)
+ self.current_info_widget = wrecipe
+ QApplication.restoreOverrideCursor()
+
+ def closeEvent(self, ev):
+ self.config.set('settings', 'backend', str(self.ui.backendEdit.itemData(
+ self.ui.backendEdit.currentIndex()).toString()))
+ self.saveSearchHistory()
+
+ self.config.save()
+ ev.accept()
diff --git a/weboob/applications/qcookboob/minirecipe.py b/weboob/applications/qcookboob/minirecipe.py
new file mode 100644
index 00000000..e53ed3c9
--- /dev/null
+++ b/weboob/applications/qcookboob/minirecipe.py
@@ -0,0 +1,66 @@
+# -*- coding: utf-8 -*-
+
+# Copyright(C) 2013 Julien Veyssier
+#
+# This file is part of weboob.
+#
+# weboob is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# weboob is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with weboob. If not, see .
+
+import urllib
+
+from PyQt4.QtGui import QFrame, QImage, QPixmap, QApplication
+from PyQt4.QtCore import Qt
+
+from weboob.applications.qcookboob.ui.minirecipe_ui import Ui_MiniRecipe
+from weboob.capabilities.base import empty
+
+
+class MiniRecipe(QFrame):
+ def __init__(self, weboob, backend, recipe, parent=None):
+ QFrame.__init__(self, parent)
+ self.parent = parent
+ self.ui = Ui_MiniRecipe()
+ self.ui.setupUi(self)
+
+ self.weboob = weboob
+ self.backend = backend
+ self.recipe = recipe
+ self.ui.titleLabel.setText(recipe.title)
+ self.ui.shortDescLabel.setText(recipe.short_description)
+ self.ui.backendLabel.setText(backend.name)
+
+ self.gotThumbnail()
+
+ def gotThumbnail(self):
+ if not empty(self.recipe.thumbnail_url):
+ data = urllib.urlopen(self.recipe.thumbnail_url).read()
+ img = QImage.fromData(data)
+ self.ui.imageLabel.setPixmap(QPixmap.fromImage(img))
+
+ def enterEvent(self, event):
+ self.setFrameShadow(self.Sunken)
+ QFrame.enterEvent(self, event)
+
+ def leaveEvent(self, event):
+ self.setFrameShadow(self.Raised)
+ QFrame.leaveEvent(self, event)
+
+ def mousePressEvent(self, event):
+ QFrame.mousePressEvent(self, event)
+
+ QApplication.setOverrideCursor(Qt.WaitCursor)
+ recipe = self.backend.get_recipe(self.recipe.id)
+ if recipe:
+ self.parent.doAction('Details of recipe "%s"' %
+ recipe.title, self.parent.displayMovie, [recipe, self.backend])
diff --git a/weboob/applications/qcookboob/qcookboob.py b/weboob/applications/qcookboob/qcookboob.py
new file mode 100644
index 00000000..5cab168f
--- /dev/null
+++ b/weboob/applications/qcookboob/qcookboob.py
@@ -0,0 +1,44 @@
+# -*- coding: utf-8 -*-
+
+# Copyright(C) 2013 Julien Veyssier
+#
+# This file is part of weboob.
+#
+# weboob is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# weboob is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with weboob. If not, see .
+
+
+from weboob.capabilities.recipe import ICapRecipe
+from weboob.tools.application.qt import QtApplication
+
+from .main_window import MainWindow
+
+
+class QCookboob(QtApplication):
+ APPNAME = 'qcookboob'
+ VERSION = '0.f'
+ COPYRIGHT = 'Copyright(C) 2013 Julien Veyssier'
+ DESCRIPTION = "Qt application allowing to search recipes."
+ SHORT_DESCRIPTION = "search recipes"
+ CAPS = ICapRecipe
+ CONFIG = {'settings': {'backend': '',
+ }
+ }
+
+ def main(self, argv):
+ self.load_backends([ICapRecipe])
+ self.load_config()
+
+ self.main_window = MainWindow(self.config, self.weboob)
+ self.main_window.show()
+ return self.weboob.loop()
diff --git a/weboob/applications/qcookboob/recipe.py b/weboob/applications/qcookboob/recipe.py
new file mode 100644
index 00000000..4254e061
--- /dev/null
+++ b/weboob/applications/qcookboob/recipe.py
@@ -0,0 +1,81 @@
+# -*- coding: utf-8 -*-
+
+# Copyright(C) 2013 Julien Veyssier
+#
+# This file is part of weboob.
+#
+# weboob is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# weboob is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with weboob. If not, see .
+
+import urllib
+
+from PyQt4.QtCore import Qt, SIGNAL
+from PyQt4.QtGui import QFrame, QImage, QPixmap
+
+from weboob.applications.qcookboob.ui.recipe_ui import Ui_Recipe
+from weboob.capabilities.base import empty
+
+
+class Recipe(QFrame):
+ def __init__(self, recipe, backend, parent=None):
+ QFrame.__init__(self, parent)
+ self.parent = parent
+ self.ui = Ui_Recipe()
+ self.ui.setupUi(self)
+ langs = LANGUAGE_CONV.keys()
+ langs.sort()
+ for lang in langs:
+ self.ui.langCombo.addItem(lang)
+
+ self.recipe = recipe
+ self.backend = backend
+ self.ui.titleLabel.setText(recipe.original_title)
+ self.ui.durationLabel.setText(unicode(recipe.duration))
+ self.gotThumbnail()
+
+ self.ui.idEdit.setText(u'%s@%s' % (recipe.id, backend.name))
+ if not empty(recipe.other_titles):
+ self.ui.otherTitlesPlain.setPlainText('\n'.join(recipe.other_titles))
+ else:
+ self.ui.otherTitlesPlain.parent().hide()
+ if not empty(recipe.release_date):
+ self.ui.releaseDateLabel.setText(recipe.release_date.strftime('%Y-%m-%d'))
+ else:
+ self.ui.releaseDateLabel.parent().hide()
+ if not empty(recipe.duration):
+ self.ui.durationLabel.setText('%s min' % recipe.duration)
+ else:
+ self.ui.durationLabel.parent().hide()
+ if not empty(recipe.pitch):
+ self.ui.pitchPlain.setPlainText('%s' % recipe.pitch)
+ else:
+ self.ui.pitchPlain.parent().hide()
+ if not empty(recipe.country):
+ self.ui.countryLabel.setText('%s' % recipe.country)
+ else:
+ self.ui.countryLabel.parent().hide()
+ if not empty(recipe.note):
+ self.ui.noteLabel.setText('%s' % recipe.note)
+ else:
+ self.ui.noteLabel.parent().hide()
+ for role in ROLE_LIST:
+ self.ui.castingCombo.addItem('%ss' % role)
+
+ self.ui.verticalLayout.setAlignment(Qt.AlignTop)
+ self.ui.verticalLayout_2.setAlignment(Qt.AlignTop)
+
+ def gotThumbnail(self):
+ if not empty(self.recipe.thumbnail_url):
+ data = urllib.urlopen(self.recipe.thumbnail_url).read()
+ img = QImage.fromData(data)
+ self.ui.imageLabel.setPixmap(QPixmap.fromImage(img))
diff --git a/weboob/applications/qcookboob/ui/Makefile b/weboob/applications/qcookboob/ui/Makefile
new file mode 100644
index 00000000..f0db5154
--- /dev/null
+++ b/weboob/applications/qcookboob/ui/Makefile
@@ -0,0 +1,13 @@
+UI_FILES = $(wildcard *.ui)
+UI_PY_FILES = $(UI_FILES:%.ui=%_ui.py)
+PYUIC = pyuic4
+
+all: $(UI_PY_FILES)
+
+%_ui.py: %.ui
+ $(PYUIC) -o $@ $^
+
+clean:
+ rm -f *.pyc
+ rm -f $(UI_PY_FILES)
+
diff --git a/weboob/applications/qcookboob/ui/__init__.py b/weboob/applications/qcookboob/ui/__init__.py
new file mode 100644
index 00000000..e69de29b
diff --git a/weboob/applications/qcookboob/ui/main_window.ui b/weboob/applications/qcookboob/ui/main_window.ui
new file mode 100644
index 00000000..dcf213df
--- /dev/null
+++ b/weboob/applications/qcookboob/ui/main_window.ui
@@ -0,0 +1,257 @@
+
+
+ MainWindow
+
+
+
+ 0
+ 0
+ 748
+ 463
+
+
+
+ QCineoob
+
+
+
+
+ 4
+
+ -
+
+
+ QFrame::StyledPanel
+
+
+ QFrame::Raised
+
+
+
+ 0
+
+
+ 0
+
+
-
+
+
+ Search:
+
+
+
+ -
+
+
+ -
+
+
-
+
+ movie
+
+
+ -
+
+ person
+
+
+ -
+
+ torrent
+
+
+ -
+
+ subtitle
+
+
+
+
+ -
+
+
+
+ 8
+
+
+
+ language
+
+
+
+ -
+
+
+ -
+
+
+
+
+
+ -
+
+
+ QFrame::NoFrame
+
+
+ QFrame::Raised
+
+
+
+ 0
+
+
+ 0
+
+
-
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+
+ 60
+ 20
+
+
+
+ <<back
+
+
+
+ -
+
+
+
+ 75
+ true
+
+
+
+
+
+
+ Qt::AlignCenter
+
+
+ true
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
+
+
+ -
+
+
+
+
-
+
+
+ true
+
+
+
+
+ 0
+ 0
+ 708
+ 292
+
+
+
+
+
+
+
+
+
+
+ -
+
+
+ true
+
+
+
+
+ 0
+ 0
+ 63
+ 18
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ toolBar
+
+
+ TopToolBarArea
+
+
+ false
+
+
+
+
+
+
+ Backends
+
+
+
+
+ Quit
+
+
+ Ctrl+Q
+
+
+
+
+
+
diff --git a/weboob/applications/qcookboob/ui/minirecipe.ui b/weboob/applications/qcookboob/ui/minirecipe.ui
new file mode 100644
index 00000000..b952ceae
--- /dev/null
+++ b/weboob/applications/qcookboob/ui/minirecipe.ui
@@ -0,0 +1,135 @@
+
+
+ MiniRecipe
+
+
+
+ 0
+ 0
+ 464
+ 136
+
+
+
+ Form
+
+
+ QFrame::StyledPanel
+
+
+ QFrame::Raised
+
+
+
+ 9
+
+
+ 5
+
+
+ 5
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+
+
+
+ -
+
+
+ QFormLayout::ExpandingFieldsGrow
+
+
-
+
+
+
+ 75
+ true
+
+
+
+ Title
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 50
+ true
+ false
+
+
+
+ TextLabel
+
+
+ true
+
+
+
+ -
+
+
+
+ 75
+ true
+
+
+
+ Short description:
+
+
+
+ -
+
+
+ TextLabel
+
+
+ true
+
+
+
+ -
+
+
+
+ 75
+ true
+
+
+
+ Where
+
+
+
+ -
+
+
+ TextLabel
+
+
+
+
+
+
+
+
+
+
diff --git a/weboob/applications/qcookboob/ui/recipe.ui b/weboob/applications/qcookboob/ui/recipe.ui
new file mode 100644
index 00000000..2891fd96
--- /dev/null
+++ b/weboob/applications/qcookboob/ui/recipe.ui
@@ -0,0 +1,478 @@
+
+
+ Recipe
+
+
+
+ 0
+ 0
+ 645
+ 600
+
+
+
+
+ 0
+ 0
+
+
+
+
+ 2000
+ 600
+
+
+
+ Frame
+
+
+ QFrame::StyledPanel
+
+
+ QFrame::Raised
+
+
+ -
+
+
+
+ 16777215
+ 3000
+
+
+
+ QFrame::NoFrame
+
+
+ QFrame::Raised
+
+
+
-
+
+
+
+
+
+
+ -
+
+
+ QFrame::NoFrame
+
+
+ QFrame::Raised
+
+
+
+ 0
+
+
+ 0
+
+
-
+
+
+ view casting
+
+
+
+ -
+
+
-
+
+ all
+
+
+
+
+
+
+
+ -
+
+
+ QFrame::NoFrame
+
+
+ QFrame::Raised
+
+
+
+ 0
+
+
+ 0
+
+
-
+
+
+ search torrents
+
+
+
+
+
+
+ -
+
+
+ QFrame::NoFrame
+
+
+ QFrame::Raised
+
+
+
+ 0
+
+
+ 0
+
+
-
+
+
+ search subtitles
+
+
+
+ -
+
+
+
+
+
+
+
+
+ -
+
+
+
+ 16777215
+ 600
+
+
+
+ QFrame::NoFrame
+
+
+ QFrame::Raised
+
+
+
-
+
+
+
+ 16777215
+ 40
+
+
+
+ QFrame::StyledPanel
+
+
+ QFrame::Raised
+
+
+
+ 3
+
+
+ 3
+
+
-
+
+
+ Id:
+
+
+
+ -
+
+
+ Qt::AlignCenter
+
+
+ true
+
+
+
+
+
+
+ -
+
+
+
+ 16777215
+ 35
+
+
+
+ QFrame::StyledPanel
+
+
+ QFrame::Raised
+
+
+
-
+
+
+ Title:
+
+
+
+ -
+
+
+
+
+
+
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 16777215
+ 200
+
+
+
+ QFrame::StyledPanel
+
+
+ QFrame::Raised
+
+
+
-
+
+
+
+ 100
+ 16777215
+
+
+
+ Other titles:
+
+
+
+ -
+
+
+ Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse
+
+
+
+
+
+
+ -
+
+
+
+ 16777215
+ 35
+
+
+
+ QFrame::StyledPanel
+
+
+ QFrame::Raised
+
+
+
-
+
+
+ Duration:
+
+
+
+ -
+
+
+
+
+
+
+
+
+
+ -
+
+
+
+ 16777215
+ 35
+
+
+
+ QFrame::StyledPanel
+
+
+ QFrame::Raised
+
+
+
-
+
+
+ Release date:
+
+
+
+ -
+
+
+
+
+
+
+
+
+
+ -
+
+
+
+ 16777215
+ 200
+
+
+
+ QFrame::StyledPanel
+
+
+ QFrame::Raised
+
+
+
-
+
+
+ Pitch:
+
+
+
+ -
+
+
+ Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse
+
+
+
+
+
+
+ -
+
+
+
+ 16777215
+ 35
+
+
+
+ QFrame::StyledPanel
+
+
+ QFrame::Raised
+
+
+
-
+
+
+ Country:
+
+
+
+ -
+
+
+
+
+
+
+
+
+
+ -
+
+
+
+ 16777215
+ 35
+
+
+
+ QFrame::StyledPanel
+
+
+ QFrame::Raised
+
+
+
-
+
+
+ Note:
+
+
+
+ -
+
+
+
+
+
+
+
+
+
+ -
+
+
+
+ 16777215
+ 200
+
+
+
+ QFrame::StyledPanel
+
+
+ QFrame::Raised
+
+
+
-
+
+
+ All release dates:
+
+
+
+ -
+
+
+ Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse
+
+
+
+
+
+
+
+
+
+
+
+
+
+