class BufferSelectToolbar(object):
    def __init__(self, selectTool):
        super(BufferSelectToolbar, self).__init__()
        # references
        self.selectTool = selectTool
        self.result = None
        self.debug = self.selectTool.debug
        self.id = id
        self.config = self.selectTool.config
        self.info = Info(self)
        try:
            self.gtomain = self.selectTool.gtomain
            self.helper = self.gtomain.helper
            self.metadata = self.gtomain.metadata
            self.iface = self.gtomain.iface
            self.canvas = self.iface.mapCanvas()
            # tool data
            self.toolbar_dock = self.config.get("toolbar_dock", 4)
            self.toolbar_height = self.gtomain.toolbar_height
            # widget
            self.toolbar = None
            # load toolbar
            objName = "gtoTB_" + __name__ + str(id)
            self.toolbar = self.gtomain.helper.findToolbar(self.iface, objName)
            if self.toolbar is None:
                if self.debug: self.info.log("load", objName)
                self.toolbar = QToolBar()
                self.toolbar.setObjectName(objName)
                self.toolbar.setWindowTitle(u'GTO Buffer Selection')
                self.toolbar.setAllowedAreas(Qt.BottomToolBarArea
                                             | Qt.TopToolBarArea)
                self.iface.mainWindow().addToolBarBreak(self.toolbar_dock)
                self.iface.addToolBar(self.toolbar, self.toolbar_dock)
                # set the iconsize=> changed when self.iface.addToolBar :S
                if self.toolbar_height is not None:
                    self.toolbar.setMaximumHeight(self.gtomain.toolbar_height)
                    self.toolbar.setMinimumHeight(self.gtomain.toolbar_height)
            else:
                self.toolbar.clear()
            self.wid = Widget(self)
            self.toolbar.addWidget(self.wid)
            self.wid.setIconSizes(self.iface.iconSize(False))
            self.wid.geometry_changed.connect(self.getGeometry)
            self.toolbar.setHidden(False)
        except Exception as e:
            self.info.err(e)

    # from mActionbufferselectxy
    def setHidden(self, a0):
        self.toolbar.setHidden(a0)

    def setGeometry(self, geo, isValid, isCircle=False, isRectangle=False):
        self.toolbar.setHidden(False)
        if self.debug:
            self.info.log("setGeometry", geo.isEmpty(), isValid, isCircle,
                          isRectangle)
        self.wid.setOriginalGeometry(geo, isValid, isCircle, isRectangle)

    def getGeometry(self, geo):
        self.selectTool.setGeometryToMapTool(geo)
Esempio n. 2
0
class Tab(QWidget):
    """Tab in the QTableWidget where user executes query and sees the result."""

    # ----------------------------------------------------------------------
    def __init__(self):
        """Initialize Tab with layout and behavior."""
        super(Tab, self).__init__()

        # regex pattern for SQL query block comments
        self.block_comment_re = re.compile(
            r'(^)?[^\S\n]*/(?:\*(.*?)\*/[^\S\n]*|/[^\n]*)($)?',
            re.DOTALL | re.MULTILINE)

        main_layout = QVBoxLayout(self)

        # define gdb props
        self.gdb = None
        self.gdb_items = None
        self.gdb_columns_names = None
        self.gdb_schemas = None

        # connected geodatabase path toolbar
        self.connected_gdb_path_label = QLabel('')
        self.connected_gdb_path_label.setTextInteractionFlags(
            Qt.TextSelectableByMouse)
        self.connected_gdb_path_label.setToolTip(
            'Connected geodatabase that queries will be run against')
        self.connected_gdb_path_label.setText(not_connected_to_gdb_message)

        self.browse_to_gdb = QPushButton('Browse')
        self.browse_to_gdb.setShortcut(QKeySequence('Ctrl+B'))
        self.browse_to_gdb.clicked.connect(
            lambda evt, arg=True: self.connect_to_geodatabase(
                evt, triggered_with_browse=True))

        self.gdb_sql_dialect_combobox = QComboBox()
        for dialect in sql_dialects_names:
            self.gdb_sql_dialect_combobox.addItem(dialect)

        self.gdb_browse_toolbar = QToolBar()
        self.gdb_browse_toolbar.setMaximumHeight(50)
        self.gdb_browse_toolbar.addWidget(self.browse_to_gdb)
        self.gdb_browse_toolbar.addWidget(self.connected_gdb_path_label)
        self.gdb_browse_toolbar.addSeparator()
        self.gdb_browse_toolbar.addWidget(self.gdb_sql_dialect_combobox)

        # table with results
        self.table = ResultTable()

        # execute SQL query
        self.execute = QAction('Execute', self)
        self.execute.setShortcuts(
            [QKeySequence('F5'),
             QKeySequence('Ctrl+Return')])
        self.execute.triggered.connect(self.run_query)
        self.addAction(self.execute)

        # enter a SQL query
        self.query = TextEditor()
        self.query.setPlainText('')
        font = self.query.font()
        font.setFamily('Consolas')
        font.setStyleHint(QFont.Monospace)

        # TODO: add line numbers to the text editor
        font.setPointSize(14)
        self.query.setFont(font)
        self.query.setTabStopWidth(20)
        self.highlighter = Highlighter(self.query.document())

        # TODO select block of text - Ctrl+/ and they become comments
        self.completer = Completer()
        self.query.set_completer(self.completer.completer)

        # errors panel to show if query fails to execute properly
        self.errors_panel = QPlainTextEdit()
        font = self.query.font()
        font.setPointSize(12)
        self.errors_panel.setStyleSheet('color:red')
        self.errors_panel.setFont(font)
        self.errors_panel.hide()

        # splitter between the toolbar, query window, and the result set table
        splitter = QSplitter(Qt.Vertical)
        splitter.addWidget(self.gdb_browse_toolbar)
        splitter.addWidget(self.query)
        splitter.addWidget(self.table)
        splitter.addWidget(self.errors_panel)

        # add the settings after the widget have been added
        splitter.setCollapsible(0, True)
        splitter.setCollapsible(1, False)
        splitter.setCollapsible(2, False)
        splitter.setCollapsible(3, False)
        splitter.setStretchFactor(0, 3)
        splitter.setStretchFactor(1, 7)
        splitter.setSizes((100, 200, 300))
        self.table.hide()

        # TOC
        self.toc = QTreeWidget()
        self.toc.setHeaderHidden(True)

        # second splitter between the TOC to the left and the query/table to the
        # right
        toc_splitter = QSplitter(Qt.Horizontal)
        toc_splitter.addWidget(self.toc)
        toc_splitter.addWidget(splitter)
        toc_splitter.setCollapsible(0, True)
        toc_splitter.setSizes((200, 800))  # set the TOC vs data panel

        main_layout.addWidget(toc_splitter)

        margins = QMargins()
        margins.setBottom(10)
        margins.setLeft(10)
        margins.setRight(10)
        margins.setTop(10)
        main_layout.setContentsMargins(margins)

        self.setLayout(main_layout)
        QApplication.setStyle(QStyleFactory.create('Cleanlooks'))
        self.show()

        return

    # ----------------------------------------------------------------------
    def connect_to_geodatabase(self, evt, triggered_with_browse=True):
        """Connect to geodatabase by letting user browse to a gdb folder."""
        if triggered_with_browse:
            gdb_connect_dialog = QFileDialog(self)
            gdb_connect_dialog.setFileMode(QFileDialog.Directory)
            gdb_path = gdb_connect_dialog.getExistingDirectory()

            # TODO: add a filter to show only .gdb folders?
            # https://stackoverflow.com/questions/4893122/filtering-in-qfiledialog
            if gdb_path and gdb_path.endswith('.gdb'):
                self.gdb = Geodatabase(gdb_path)
                if self.gdb.is_valid():
                    self.connected_gdb_path_label.setText(self.gdb.path)
                    self._set_gdb_items_highlight()
                    self._set_gdb_items_complete()
                    self._fill_toc()
                else:
                    msg = QMessageBox()
                    msg.setText('This is not a valid file geodatabase')
                    msg.setWindowTitle('Validation error')
                    msg.setStandardButtons(QMessageBox.Ok)
                    msg.exec_()
        else:
            if self.gdb.is_valid():
                self._set_gdb_items_highlight()
                self._set_gdb_items_complete()

        return

    # ----------------------------------------------------------------------
    def wheelEvent(self, event):  # noqa: N802
        """Override built-in method to handle mouse wheel scrolling.

        Necessary to do when the tab is focused.
        """
        modifiers = QApplication.keyboardModifiers()
        if modifiers == Qt.ControlModifier:
            if event.angleDelta().y() > 0:  # scroll forward
                self.query.zoomIn(1)
            else:
                self.query.zoomOut(1)
        return

    # ----------------------------------------------------------------------
    def run_query(self):
        """Run SQL query and draw the record set and call table drawing."""
        if not self.gdb:
            self.print_sql_execute_errors(not_connected_to_gdb_message)
            return
        try:
            if not self.gdb.is_valid():
                return

            # use the text of what user selected, if none -> need to run the
            # whole query
            part_sql_query = self.query.textCursor().selection().toPlainText()

            if part_sql_query:
                sql_query = part_sql_query
            else:
                sql_query = self.query.toPlainText()

            if sql_query:
                # removing block comments and single line comments
                sql_query = self.block_comment_re.sub(
                    self._strip_block_comments, sql_query)
                sql_query = self._strip_single_comments(sql_query)
            else:
                return

            # TODO: add threading to allow user to cancel a long running query
            QApplication.setOverrideCursor(Qt.WaitCursor)
            start_time = time.time()
            self.gdb.open_connection()
            res, errors = self.gdb.execute_sql(
                sql_query, self.gdb_sql_dialect_combobox.currentText())
            end_time = time.time()
            if errors:
                self.print_sql_execute_errors(errors)

            if res:
                self.table.show()
                self.errors_panel.hide()
                self.draw_result_table(res)
                msg = 'Executed in {exec_time:.1f} secs | {rows} rows'.format(
                    exec_time=end_time - start_time,
                    rows=self.table.table_data.number_layer_rows)
                self.update_app_status_bar(msg)

        except Exception as err:
            print(err)
        finally:
            QApplication.restoreOverrideCursor()
        return

    # ----------------------------------------------------------------------
    def result_should_include_geometry(self):
        """Get the setting defining whether to include the geometry column."""
        try:
            return self.parentWidget().parentWidget().parentWidget(
            ).do_include_geometry.isChecked()
        except Exception:
            return True

    # ----------------------------------------------------------------------
    def update_app_status_bar(self, message):
        """Update app status bar with the execution result details."""
        try:
            self.parentWidget().parentWidget().parentWidget().statusBar(
            ).showMessage(message)
        except Exception:
            pass
        return

    # ----------------------------------------------------------------------
    def draw_result_table(self, res):
        """Draw table with the record set received from the geodatabase."""
        geom_col_name = res.GetGeometryColumn(
        )  # shape col was in the sql query
        self.geometry_isin_query = bool(geom_col_name)

        self.table.draw_result(res,
                               show_shapes=bool(
                                   self.result_should_include_geometry()))
        self.table.view.resizeColumnsToContents()
        return

    # ----------------------------------------------------------------------
    def print_sql_execute_errors(self, err):
        """Print to a special panel errors that occurred during execution."""
        self.table.hide()
        self.errors_panel.show()
        self.errors_panel.setPlainText(err)
        return

    # ----------------------------------------------------------------------
    def _set_gdb_items_highlight(self):
        """Set completer and highlight properties for geodatabase items."""
        self.gdb_items = self.gdb.get_items()
        self.highlighter.set_highlight_rules_gdb_items(self.gdb_items, 'Table')

        self.gdb_schemas = self.gdb.get_schemas()
        self.gdb_columns_names = sorted(list(
            set(
                itertools.chain.from_iterable(
                    [i.keys() for i in self.gdb_schemas.values()]))),
                                        key=lambda x: x.lower())

    # ----------------------------------------------------------------------
    def _set_gdb_items_complete(self):
        """Update completer rules to include geodatabase items."""
        self.completer.update_completer_string_list(self.gdb_items +
                                                    self.gdb_columns_names)
        self.highlighter.set_highlight_rules_gdb_items(self.gdb_columns_names,
                                                       'Column')
        return

    # ----------------------------------------------------------------------
    def _fill_toc(self):
        """Fill TOC with geodatabase datasets and columns."""
        self.toc.clear()
        if not self.gdb_items:
            return

        for tbl_name in sorted(self.gdb_items, key=lambda i: i.lower()):
            if tbl_name.islower() or tbl_name.isupper():
                item = QTreeWidgetItem([tbl_name.title()])
            else:
                item = QTreeWidgetItem([tbl_name])
            font = QFont()
            font.setBold(True)
            item.setFont(0, font)

            for col_name, col_type in sorted(
                    self.gdb_schemas[tbl_name].items()):
                if col_name.islower() or col_name.isupper():
                    col_name = col_name.title()

                item_child = QTreeWidgetItem(
                    ['{0} ({1})'.format(col_name, col_type)])
                item.addChild(item_child)
            self.toc.addTopLevelItem(item)
        return

    # ----------------------------------------------------------------------
    def _do_toc_hide_show(self):
        """Hide TOC with tables and columns."""
        if self.toc.isVisible():
            self.toc.setVisible(False)
        else:
            self.toc.setVisible(True)
        return

    # ----------------------------------------------------------------------
    def _strip_block_comments(self, sql_query):
        """Strip the block comments in SQL query."""
        start, mid, end = sql_query.group(1, 2, 3)
        if mid is None:
            # this is a single-line comment
            return ''
        elif start is not None or end is not None:
            # this is a multi-line comment at start/end of a line
            return ''
        elif '\n' in mid:
            # this is a multi-line comment with line break
            return '\n'
        else:
            # this is a multi-line comment without line break
            return ' '

    # ----------------------------------------------------------------------
    def _strip_single_comments(self, sql_query):
        """Strip the single line comments in SQL query."""
        clean_query = []
        for line in sql_query.rstrip().split('\n'):
            clean_line = line.split('--')[0]
            if clean_line:
                clean_query.append(clean_line)
        return ' '.join([line for line in clean_query])
Esempio n. 3
0
class MainWindow(QMainWindow):

    # initialize the main window
    def __init__(self, parent=None):
        QMainWindow.__init__(self, parent)
        self.init_ui()
        self.show()
        self.rgb = [128, 128, 128]
        self.xy = [0, 0]
        self.hw = [0, 0]
        self.filter = 1
        self.handler.handle_open_for_json()
        QApplication.clipboard().dataChanged.connect(self.clipboardChanged)
        self.clipboardChanged()
        self.resize(1280, 768)
        # self.handler.handle_stow()

    def init_ui(self):
        self.setWindowTitle("Cute Image Editor")
        self.central_widget = QWidget()
        self.gridLayout = QGridLayout()
        self.central_widget.setLayout(self.gridLayout)
        self.setCentralWidget(self.central_widget)
        self.resize(1280, 768)

        # Add the click handler
        self.handler = ClickHandler(self)

        # Main editing area
        self.mdiArea = IWindow(self)
        # Left window~
        self.lwindow = LWindow(self)
        # Right window
        self.rwindow = RWindow(self)
        # Bottom window
        self.bwindow = BWindow(self)

        # Add components to the main grid layout
        self.init_grid()

        self.init_tool_bar()
        self.init_menu_bar()

    def init_grid(self):
        self.gridLayout.setSpacing(2)
        self.gridLayout.addWidget(self.lwindow, 1, 1)
        self.gridLayout.addWidget(self.mdiArea, 1, 2)
        self.gridLayout.addWidget(self.rwindow, 1, 3)
        self.gridLayout.addWidget(self.bwindow, 2, 1, 1, 3)
        self.gridLayout.setColumnMinimumWidth(1, 220)
        self.gridLayout.setColumnMinimumWidth(2, 900)
        self.gridLayout.setColumnMinimumWidth(3, 220)
        self.gridLayout.setRowMinimumHeight(1, 500)
        self.gridLayout.setRowMinimumHeight(2, 140)

    def init_tool_bar(self):

        self.toolbar = QToolBar("Shortcuts")
        self.addToolBar(self.toolbar)
        # action_list = [[self.open_action, self.save_action, self.info_action, self.quit_action, self.search_help_action],
        #                [self.original_color_action, self.reverse_action, self.to_grayscale_action, self],
        #                [self.saturate_red_action, self.saturate_blue_action, self.saturate_green_action],
        #                [self.threshold_action, self.blur_action, self.sharpen_action],
        #                [self.ccl_action, self.hsl_action, self.outline_action],
        #                [self.floyd_action, self.rgb_action, self.crop_action]]
        # for sublist in action_list:
        #     for action in sublist:
        #         self.toolbar.addAction(QAction(action))
        #     self.toolbar.addSeparator()
        self.toolbar.setMaximumHeight(30)
        self.toolbar.setMinimumHeight(30)

    def init_menu_bar(self):
        # Create menus in the menu bar as following
        # File  Edit  View  Image  Processing  Profile  Window  Help
        self.file_menu = QMenu("&File")
        self.menuBar().addMenu(self.file_menu)
        self.edit_menu = QMenu("&Edit")
        self.menuBar().addMenu(self.edit_menu)
        self.view_menu = QMenu("&View")
        self.menuBar().addMenu(self.view_menu)
        self.image_menu = QMenu("&Image")
        self.menuBar().addMenu(self.image_menu)
        self.processing_menu = QMenu("Processing")
        self.menuBar().addMenu(self.processing_menu)
        self.share_menu = QMenu("Share")
        self.menuBar().addMenu(self.share_menu)
        self.window_menu = QMenu("&Window")
        self.menuBar().addMenu(self.window_menu)
        self.help_menu = QMenu("&Help")
        self.menuBar().addMenu(self.help_menu)

        # Create actions for each menu
        # Actions for File menu
        self.open_action = MyImageAction(self, "&Open...", self.file_menu,
                                         self.handler.handle_open, "Ctrl+O",
                                         "open.png")
        self.save_action = MyImageAction(self, "&Save...", self.file_menu,
                                         self.handler.handle_save, "Ctrl+S",
                                         "save_as.png")
        self.info_action = MyImageAction(self, "&Get Info...", self.file_menu,
                                         self.handler.handle_info, "Ctrl+I",
                                         "info.png")
        self.camera_action = MyImageAction(self, "&Camera", self.edit_menu,
                                           self.handler.handle_camera, "",
                                           "camera.png")
        self.url_action = MyImageAction(self, "&Open URL", self.edit_menu,
                                        self.handler.handle_url, "", "url.png")
        self.clipboard_action = MyImageAction(self, "&Copy To Clipboard",
                                              self.edit_menu,
                                              self.handler.handle_clipboard,
                                              "", "clipboard.png")
        self.show_folder_action = MyImageAction(self, "&Show In Finder",
                                                self.file_menu,
                                                self.handler.handle_finder,
                                                "Ctrl+F", "finder.png")
        self.open_with_app_action = MyImageAction(
            self, "&Open With App", self.file_menu,
            self.handler.handle_open_with_app, "", "app.png")
        self.instagram_action = MyImageAction(self, "&Share In Instagram",
                                              self.share_menu,
                                              self.handler.handle_instagram,
                                              "", "instagram.png")
        self.twitter_action = MyImageAction(self, "&Share In Twitter",
                                            self.share_menu,
                                            self.handler.handle_twitter, "",
                                            "twitter.png")
        self.snapchat_action = MyImageAction(self, "&Share In Snapchat",
                                             self.share_menu,
                                             self.handler.handle_snapchat, "",
                                             "snapchat.png")
        # Actions for Processing menu
        self.original_color_action = MyImageAction(
            self, "&Original color", self.image_menu,
            self.handler.handle_original_color, "", "origin.png")
        self.reverse_action = MyImageAction(self, "&Reverse", self.image_menu,
                                            self.handler.handle_reverse, "",
                                            "reverse.png")
        self.to_grayscale_action = MyImageAction(
            self, "&Black and white", self.image_menu,
            self.handler.handle_to_grayscale, "", "to_grayscale.png")
        self.image_menu.addSeparator()
        self.saturate_red_action = MyImageAction(
            self, "&Saturate in red", self.image_menu,
            self.handler.handle_saturate_red, "", "saturate_red.png")
        self.saturate_green_action = MyImageAction(
            self, "&Saturate in green", self.image_menu,
            self.handler.handle_saturate_green, "", "saturate_green.png")
        self.saturate_blue_action = MyImageAction(
            self, "&Saturate in blue", self.image_menu,
            self.handler.handle_saturate_blue, "", "saturate_blue.png")

        self.threshold_action = MyImageAction(self, "&Threshold",
                                              self.processing_menu,
                                              self.handler.handle_threshold,
                                              "", "threshold.png")

        self.blur_action = MyImageAction(self, "&Blur", self.processing_menu,
                                         self.handler.handle_blur, "",
                                         "blur.png")
        self.gaussian_blur_action = MyImageAction(
            self, "&Gaussian Blur", self.processing_menu,
            self.handler.handle_gaussian_blur, "", "gaussian.png")
        self.box_blur_action = MyImageAction(self, "&Box Blur",
                                             self.processing_menu,
                                             self.handler.handle_box_blur, "",
                                             "box.png")
        self.sharpen_action = MyImageAction(self, "&Sharpen",
                                            self.processing_menu,
                                            self.handler.handle_sharpen, "",
                                            "sharpen.png")
        self.processing_menu.addSeparator()
        self.filter_action = MyImageAction(self, "&Filter",
                                           self.processing_menu,
                                           self.handler.handle_filter, "",
                                           "filter.png")
        self.ccl_action = MyImageAction(self, "&CCL", self.processing_menu,
                                        self.handler.handle_ccl, "", "CCL.png")
        # self.hsl_action = MyImageAction(self, "&HSL", self.processing_menu, self.handler.handle_hsl, "", "hsl.png")
        self.outline_action = MyImageAction(self, "&Outline detection",
                                            self.processing_menu,
                                            self.handler.handle_outline, "",
                                            "outline.png")
        self.smooth_action = MyImageAction(self, "&Smooth",
                                           self.processing_menu,
                                           self.handler.handle_smooth, "",
                                           "smooth.png")
        self.smooth_more_action = MyImageAction(
            self, "&Smooth More", self.processing_menu,
            self.handler.handle_smooth_more, "", "smooth.png")
        self.detail_action = MyImageAction(self, "&Detail",
                                           self.processing_menu,
                                           self.handler.handle_detail, "",
                                           "detail.png")
        self.emboss_action = MyImageAction(self, "&Emboss",
                                           self.processing_menu,
                                           self.handler.handle_emboss, "",
                                           "emboss.png")
        self.edge_action = MyImageAction(self, "&Edge", self.processing_menu,
                                         self.handler.handle_edge, "",
                                         "edge.png")
        self.edge_more_action = MyImageAction(self, "&Edge More",
                                              self.processing_menu,
                                              self.handler.handle_edge_more,
                                              "", "edge.png")
        self.find_edges_action = MyImageAction(self, "&Find Edges",
                                               self.processing_menu,
                                               self.handler.handle_find_edges,
                                               "", "find_edges.png")

        self.processing_menu.addSeparator()
        self.min_filter_action = MyImageAction(self, "&Min Filter",
                                               self.processing_menu,
                                               self.handler.handle_min_filter,
                                               "", "filter-512.png")
        self.max_filter_action = MyImageAction(self, "&Max Filter",
                                               self.processing_menu,
                                               self.handler.handle_max_filter,
                                               "", "filter-512.png")
        self.median_filter_action = MyImageAction(
            self, "&Median Filter", self.processing_menu,
            self.handler.handle_median_filter, "", "filter-512.png")
        self.rank_filter_action = MyImageAction(
            self, "&Rank Filter", self.processing_menu,
            self.handler.handle_rank_filter, "", "filter-512.png")

        self.processing_menu.addSeparator()
        self.floyd_action = MyImageAction(self, "&Dithering",
                                          self.processing_menu,
                                          self.handler.handle_dithering, "",
                                          "floyd.png")
        self.rgb_action = MyImageAction(self, "&RGB", self.processing_menu,
                                        self.handler.handle_rgb, "", "rgb.png")
        self.crop_action = MyImageAction(self, "&Crop", self.processing_menu,
                                         self.handler.handle_crop, "",
                                         "crop.png")
        self.timer_action = MyImageAction(self, "&Timer", self.processing_menu,
                                          self.handler.handle_timer, "",
                                          "timer.png")
        self.kernel_action = MyImageAction(self, "&Kernel",
                                           self.processing_menu,
                                           self.handler.handle_kernel, "",
                                           "kernel.png")
        self.view_menu.addSeparator()
        self.toggle_l_action = MyImageAction(self, "&Toggle Left",
                                             self.view_menu,
                                             self.handler.handle_toggle_l,
                                             "Ctrl+1", "l_window.png")
        self.toggle_r_action = MyImageAction(self, "&Toggle Right",
                                             self.view_menu,
                                             self.handler.handle_toggle_r,
                                             "Ctrl+2", "r_window.png")
        self.toggle_b_action = MyImageAction(self, "&Toggle Bottom",
                                             self.view_menu,
                                             self.handler.handle_toggle_b,
                                             "Ctrl+0", "b_window.png")
        self.view_menu.addSeparator()
        self.close_all_action = MyImageAction(self, "&Close All",
                                              self.window_menu,
                                              self.handler.handle_close_all,
                                              "", "close.png")
        self.quit_action = MyImageAction(self, "&Quit", self.file_menu,
                                         self.close, "Ctrl+Q", "quit.png")

        self.search_help_action = QAction("&Search help...", self)
        self.actions = [
            [self.open_action, self.save_action, self.info_action],
            [self.camera_action, self.clipboard_action],
            [
                self.url_action, self.show_folder_action,
                self.open_with_app_action
            ],
            [self.instagram_action, self.twitter_action, self.snapchat_action],
            [
                QAction(),
                QAction(),
                QAction(),
                QAction(),
                QAction(),
                QAction(),
                QAction(),
                QAction(),
                QAction(),
                QAction(),
                QAction(),
                QAction(),
                QAction()
            ],
            [self.toggle_l_action, self.toggle_r_action, self.toggle_b_action],
            [self.close_all_action, self.quit_action]
        ]
        for sub_list in self.actions:
            for action in sub_list:
                self.toolbar.addAction(action)
            if sub_list != self.actions[-1] and sub_list != self.actions[
                    -3] and sub_list != self.actions[-4]:
                self.toolbar.addSeparator()

        self.help_menu.addAction(self.search_help_action)

    def get_rgb(self):
        return self.rgb

    def get_xy(self):
        return self.xy

    def get_hw(self):
        return self.hw

    def clipboardChanged(self):
        self.clip_board_text = QApplication.clipboard().text()
        self.clip_board_image = QApplication.clipboard().image()

    def set_rgb(self, r=128, g=128, b=128):
        self.rgb = [r, g, b]

    def closeEvent(self, event):
        self.handler.handle_close_event()